| | |
| | | * |
| | | * @param entryDN The distinguished name of the entry. |
| | | * |
| | | * @param subtree <code>true</code> to include all entries from the |
| | | * requested entry to the lowest level in the |
| | | * tree or <code>false</code> to only include |
| | | * the entries immediately below the requested |
| | | * entry. |
| | | * |
| | | * @return The number of subordinate entries for the requested entry |
| | | * or -1 if it can not be determined. |
| | | * |
| | | * @throws DirectoryException If a problem occurs while trying to |
| | | * retrieve the entry. |
| | | */ |
| | | public abstract long numSubordinates(DN entryDN) |
| | | public abstract long numSubordinates(DN entryDN, boolean subtree) |
| | | throws DirectoryException; |
| | | |
| | | |
| | |
| | | @Override() |
| | | public ConditionResult hasSubordinates(DN entryDN) throws DirectoryException |
| | | { |
| | | long ret = numSubordinates(entryDN); |
| | | long ret = numSubordinates(entryDN, false); |
| | | if(ret < 0) |
| | | { |
| | | return ConditionResult.UNDEFINED; |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public long numSubordinates(DN entryDN) throws DirectoryException |
| | | public long numSubordinates(DN entryDN, boolean subtree) |
| | | throws DirectoryException |
| | | { |
| | | // If the requested entry was null, then return undefined. |
| | | if (entryDN == null) |
| | |
| | | { |
| | | continue; |
| | | } |
| | | |
| | | // If subtree is included, count the number of entries for each |
| | | // backup directory. |
| | | if (subtree) |
| | | { |
| | | try |
| | | { |
| | | BackupDirectory backupDirectory = |
| | | BackupDirectory.readBackupDirectoryDescriptor(f.getPath()); |
| | | count += backupDirectory.getBackups().keySet().size(); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | return -1; |
| | | } |
| | | } |
| | | |
| | | count ++; |
| | | } |
| | | return count; |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public long numSubordinates(DN entryDN) |
| | | public long numSubordinates(DN entryDN, boolean subtree) |
| | | throws DirectoryException |
| | | { |
| | | backendLock.readLock().lock(); |
| | |
| | | } |
| | | else |
| | | { |
| | | return childDNSet.size(); |
| | | if(!subtree) |
| | | { |
| | | return childDNSet.size(); |
| | | } |
| | | else |
| | | { |
| | | long count = 0; |
| | | for(DN childDN : childDNSet) |
| | | { |
| | | count += numSubordinates(childDN, true); |
| | | count ++; |
| | | } |
| | | return count; |
| | | } |
| | | |
| | | } |
| | | } |
| | | finally |
| | |
| | | public synchronized ConditionResult hasSubordinates(DN entryDN) |
| | | throws DirectoryException |
| | | { |
| | | long ret = numSubordinates(entryDN); |
| | | long ret = numSubordinates(entryDN, false); |
| | | if(ret < 0) |
| | | { |
| | | return ConditionResult.UNDEFINED; |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public synchronized long numSubordinates(DN entryDN) |
| | | public synchronized long numSubordinates(DN entryDN, boolean subtree) |
| | | throws DirectoryException |
| | | { |
| | | // Try to look up the immediate children for the DN |
| | |
| | | return -1; |
| | | } |
| | | |
| | | return children.size(); |
| | | if(!subtree) |
| | | { |
| | | return children.size(); |
| | | } |
| | | else |
| | | { |
| | | long count = 0; |
| | | for(DN child : children) |
| | | { |
| | | count += numSubordinates(child, true); |
| | | count++; |
| | | } |
| | | return count; |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | public ConditionResult hasSubordinates(DN entryDN) |
| | | throws DirectoryException |
| | | { |
| | | long ret = numSubordinates(entryDN); |
| | | long ret = numSubordinates(entryDN, false); |
| | | if(ret < 0) |
| | | { |
| | | return ConditionResult.UNDEFINED; |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public long numSubordinates(DN entryDN) |
| | | public long numSubordinates(DN entryDN, boolean subtree) |
| | | throws DirectoryException |
| | | { |
| | | // If the requested entry was null, then return undefined. |
| | |
| | | // the number of monitor providers. |
| | | if (entryDN.equals(baseMonitorDN)) |
| | | { |
| | | // This backend is only 1 level deep so the count is the same for |
| | | // subtree and immediate subordinates. |
| | | return DirectoryServer.getMonitorProviders().size(); |
| | | } |
| | | |
| | |
| | | public ConditionResult hasSubordinates(DN entryDN) |
| | | throws DirectoryException |
| | | { |
| | | long ret = numSubordinates(entryDN); |
| | | long ret = numSubordinates(entryDN, false); |
| | | if(ret < 0) |
| | | { |
| | | return ConditionResult.UNDEFINED; |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public long numSubordinates(DN entryDN) |
| | | public long numSubordinates(DN entryDN, boolean subtree) |
| | | throws DirectoryException |
| | | { |
| | | if (entryDN == null || ! entryDN.isNullDN()) |
| | |
| | | |
| | | for (DN subBase : baseMap.keySet()) |
| | | { |
| | | if (DirectoryServer.entryExists(subBase)) |
| | | Backend b = baseMap.get(subBase); |
| | | Entry subBaseEntry = b.getEntry(subBase); |
| | | if (subBaseEntry != null) |
| | | { |
| | | count++; |
| | | if(subtree) |
| | | { |
| | | long subCount = b.numSubordinates(subBase, true); |
| | | if(subCount < 0) |
| | | { |
| | | return -1; |
| | | } |
| | | |
| | | count += subCount; |
| | | } |
| | | count ++; |
| | | } |
| | | } |
| | | |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public long numSubordinates(DN entryDN) |
| | | public long numSubordinates(DN entryDN, boolean subtree) |
| | | throws DirectoryException |
| | | { |
| | | return 0L; |
| | |
| | | */ |
| | | @Override() |
| | | public ConditionResult hasSubordinates(DN entryDN) |
| | | throws DirectoryException |
| | | throws DirectoryException |
| | | { |
| | | return ConditionResult.UNDEFINED; |
| | | throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, |
| | | ERR_HAS_SUBORDINATES_NOT_SUPPORTED.get()); |
| | | } |
| | | |
| | | |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public long numSubordinates(DN entryDN) throws DirectoryException |
| | | public long numSubordinates(DN entryDN, boolean subtree) |
| | | throws DirectoryException |
| | | { |
| | | return -1; |
| | | throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, |
| | | ERR_NUM_SUBORDINATES_NOT_SUPPORTED.get()); |
| | | } |
| | | |
| | | |
| | |
| | | return 0; |
| | | } |
| | | |
| | | /** |
| | | * This method constructs a container name from a base DN. Only alphanumeric |
| | | * characters are preserved, all other characters are replaced with an |
| | | * underscore. |
| | | * |
| | | * @param dn The base DN. |
| | | * @return The container name for the base DN. |
| | | */ |
| | | public static String getContainerName(DN dn) |
| | | { |
| | | String normStr = dn.toNormalizedString(); |
| | | StringBuilder builder = new StringBuilder(normStr.length()); |
| | | for (int i = 0; i < normStr.length(); i++) |
| | | { |
| | | char ch = normStr.charAt(i); |
| | | if (Character.isLetterOrDigit(ch)) |
| | | { |
| | | builder.append(ch); |
| | | } |
| | | else |
| | | { |
| | | builder.append('_'); |
| | | } |
| | | } |
| | | return builder.toString(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | |
| | | public ConditionResult hasSubordinates(DN entryDN) |
| | | throws DirectoryException |
| | | { |
| | | long ret = numSubordinates(entryDN); |
| | | long ret = numSubordinates(entryDN, false); |
| | | if(ret < 0) |
| | | { |
| | | return ConditionResult.UNDEFINED; |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public long numSubordinates(DN entryDN) throws DirectoryException |
| | | public long numSubordinates(DN entryDN, boolean subtree) |
| | | throws DirectoryException |
| | | { |
| | | EntryContainer ec; |
| | | if (rootContainer != null) |
| | |
| | | ec.sharedLock.lock(); |
| | | try |
| | | { |
| | | long count = ec.getNumSubordinates(entryDN); |
| | | long count = ec.getNumSubordinates(entryDN, subtree); |
| | | if(count == Long.MAX_VALUE) |
| | | { |
| | | // The index entry limit has exceeded and there is no count maintained. |
| | |
| | | * Determine the number of subordinate entries for a given entry. |
| | | * |
| | | * @param entryDN The distinguished name of the entry. |
| | | * @param subtree <code>true</code> will include all the entries under the |
| | | * given entries. <code>false</code> will only return the |
| | | * number of entries immediately under the given entry. |
| | | * @return The number of subordinate entries for the given entry or -1 if |
| | | * the entry does not exist. |
| | | * @throws DatabaseException If an error occurs in the JE database. |
| | | */ |
| | | public long getNumSubordinates(DN entryDN) throws DatabaseException |
| | | public long getNumSubordinates(DN entryDN, boolean subtree) |
| | | throws DatabaseException |
| | | { |
| | | EntryID entryID = dn2id.get(null, entryDN); |
| | | if (entryID != null) |
| | | { |
| | | DatabaseEntry key = |
| | | new DatabaseEntry(JebFormat.entryIDToDatabase(entryID.longValue())); |
| | | EntryIDSet entryIDSet = |
| | | id2children.readKey(key, null, LockMode.DEFAULT); |
| | | EntryIDSet entryIDSet; |
| | | if(!subtree) |
| | | { |
| | | entryIDSet = id2children.readKey(key, null, LockMode.DEFAULT); |
| | | } |
| | | else |
| | | { |
| | | entryIDSet = id2subtree.readKey(key, null, LockMode.DEFAULT); |
| | | } |
| | | long count = entryIDSet.size(); |
| | | if(count != Long.MAX_VALUE) |
| | | { |
| | |
| | | public ConditionResult hasSubordinates(DN entryDN) |
| | | throws DirectoryException |
| | | { |
| | | long ret = numSubordinates(entryDN); |
| | | long ret = numSubordinates(entryDN, false); |
| | | if(ret < 0) |
| | | { |
| | | return ConditionResult.UNDEFINED; |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public long numSubordinates(DN entryDN) throws DirectoryException |
| | | public long numSubordinates(DN entryDN, boolean subtree) |
| | | throws DirectoryException |
| | | { |
| | | if (entryDN == null) |
| | | { |
| | |
| | | if (entryDN.equals(taskRootDN)) |
| | | { |
| | | // scheduled and recurring parents. |
| | | return 2; |
| | | if(!subtree) |
| | | { |
| | | return 2; |
| | | } |
| | | else |
| | | { |
| | | return taskScheduler.getScheduledTaskCount() + |
| | | taskScheduler.getRecurringTaskCount() + 2; |
| | | } |
| | | } |
| | | else if (entryDN.equals(scheduledTaskParentDN)) |
| | | { |
| | |
| | | public ConditionResult hasSubordinates(DN entryDN) |
| | | throws DirectoryException |
| | | { |
| | | long ret = numSubordinates(entryDN); |
| | | if(ret < 0) |
| | | ConfigEntry baseEntry = configEntries.get(entryDN); |
| | | if(baseEntry == null) |
| | | { |
| | | return ConditionResult.UNDEFINED; |
| | | } |
| | | else if(ret == 0) |
| | | else if(baseEntry.hasChildren()) |
| | | { |
| | | return ConditionResult.FALSE; |
| | | return ConditionResult.TRUE; |
| | | } |
| | | else |
| | | { |
| | | return ConditionResult.TRUE; |
| | | return ConditionResult.FALSE; |
| | | } |
| | | } |
| | | |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public long numSubordinates(DN entryDN) |
| | | throws DirectoryException |
| | | public long numSubordinates(DN entryDN, boolean subtree) |
| | | throws DirectoryException |
| | | { |
| | | ConfigEntry baseEntry = configEntries.get(entryDN); |
| | | if (baseEntry == null) |
| | |
| | | return -1; |
| | | } |
| | | |
| | | return baseEntry.getChildren().size(); |
| | | if(!subtree) |
| | | { |
| | | return baseEntry.getChildren().size(); |
| | | } |
| | | else |
| | | { |
| | | long count = 0; |
| | | for(ConfigEntry child : baseEntry.getChildren().values()) |
| | | { |
| | | count += numSubordinates(child.getDN(), true); |
| | | count ++; |
| | | } |
| | | return count; |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | |
| | | try |
| | | { |
| | | long count = backend.numSubordinates(entry.getDN()); |
| | | long count = backend.numSubordinates(entry.getDN(), false); |
| | | if(count >= 0) |
| | | { |
| | | AttributeValue value = |
| | |
| | | |
| | | try |
| | | { |
| | | return backend.numSubordinates(entry.getDN()) >= 0; |
| | | return backend.numSubordinates(entry.getDN(), false) >= 0; |
| | | } |
| | | catch(DirectoryException de) |
| | | { |
| | |
| | | |
| | | try |
| | | { |
| | | long count = backend.numSubordinates(entry.getDN()); |
| | | long count = backend.numSubordinates(entry.getDN(), false); |
| | | if(count >= 0) |
| | | { |
| | | return Long.parseLong(value.getNormalizedStringValue()) == count; |
| | |
| | | |
| | | acquireIEContext(); |
| | | |
| | | // The number of entries to be exported is the number of entries under |
| | | // the base DN entry and the base entry itself. |
| | | long entryCount = backend.numSubordinates(baseDN, true) + 1; |
| | | ieContext.exportTarget = target; |
| | | if (initTask != null) |
| | | { |
| | | ieContext.initializeTask = initTask; |
| | | ieContext.initImportExportCounters(backend.getEntryCount()); |
| | | ieContext.initImportExportCounters(entryCount); |
| | | } |
| | | |
| | | // Send start message to the peer |
| | | InitializeTargetMessage initializeMessage = new InitializeTargetMessage( |
| | | baseDN, serverId, ieContext.exportTarget, requestorID, |
| | | backend.getEntryCount()); |
| | | baseDN, serverId, ieContext.exportTarget, requestorID, entryCount); |
| | | |
| | | broker.publish(initializeMessage); |
| | | |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public long numSubordinates(DN entryDN) |
| | | public long numSubordinates(DN entryDN, boolean subtree) |
| | | throws DirectoryException |
| | | { |
| | | throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, |
| | |
| | | assertNotNull(b); |
| | | assertTrue(b instanceof LDIFBackend); |
| | | |
| | | assertEquals(b.numSubordinates(DN.decode("o=ldif")), 1); |
| | | assertEquals(b.numSubordinates(DN.decode("uid=user.1,ou=People,o=ldif")), |
| | | 0); |
| | | assertEquals(b.numSubordinates(DN.decode("o=ldif"), false), 1); |
| | | assertEquals(b.numSubordinates(DN.decode("o=ldif"), true), 26); |
| | | assertEquals(b.numSubordinates( |
| | | DN.decode("uid=user.1,ou=People,o=ldif"), false), 0); |
| | | assertEquals(b.numSubordinates( |
| | | DN.decode("uid=user.1,ou=People,o=ldif"), true), 0); |
| | | |
| | | try |
| | | { |
| | | b.numSubordinates(DN.decode("ou=nonexistent,o=ldif")); |
| | | b.numSubordinates(DN.decode("ou=nonexistent,o=ldif"), false); |
| | | fail("Expected an exception when calling numSubordinates on a " + |
| | | "non-existent entry"); |
| | | } |
| | |
| | | public void testNumSubordinates() throws Exception |
| | | { |
| | | DN dn = DN.decode("dc=test,dc=com"); |
| | | assertEquals(backend.numSubordinates(dn), 1); |
| | | assertEquals(backend.numSubordinates(dn, false), 1); |
| | | assertEquals(backend.numSubordinates(dn, true), 13); |
| | | dn = DN.decode("ou=People,dc=test,dc=com"); |
| | | assertEquals(backend.numSubordinates(dn), 12); |
| | | assertEquals(backend.numSubordinates(dn, false), 12); |
| | | assertEquals(backend.numSubordinates(dn, true), 12); |
| | | dn = DN.decode("dc=com"); |
| | | assertEquals(backend.numSubordinates(dn), -1); |
| | | assertEquals(backend.numSubordinates(dn, false), -1); |
| | | assertEquals(backend.numSubordinates(dn, true), -1); |
| | | dn = DN.decode("dc=test1,dc=com"); |
| | | assertEquals(backend.numSubordinates(dn), 2); |
| | | assertEquals(backend.numSubordinates(dn, false), 2); |
| | | assertEquals(backend.numSubordinates(dn, true), 2); |
| | | dn = DN.decode("uid=user.10,ou=People,dc=test,dc=com"); |
| | | assertEquals(backend.numSubordinates(dn), 0); |
| | | assertEquals(backend.numSubordinates(dn, false), 0); |
| | | assertEquals(backend.numSubordinates(dn, true), 0); |
| | | dn = DN.decode("uid=does not exist,ou=People,dc=test,dc=com"); |
| | | assertEquals(backend.numSubordinates(dn), -1); |
| | | assertEquals(backend.numSubordinates(dn, false), -1); |
| | | assertEquals(backend.numSubordinates(dn, true), -1); |
| | | } |
| | | |
| | | @Test(dependsOnMethods = "testAdd") |
| | |
| | | public void testNumSubordinatesIndexEntryLimitExceeded() throws Exception |
| | | { |
| | | DN dn = DN.decode("dc=test,dc=com"); |
| | | assertEquals(backend.numSubordinates(dn), 1); |
| | | assertEquals(backend.numSubordinates(dn, false), 1); |
| | | assertEquals(backend.numSubordinates(dn, true), 14); |
| | | |
| | | // 1 entry was deleted and 2 added for a total of 13 |
| | | dn = DN.decode("ou=People,dc=test,dc=com"); |
| | | assertEquals(backend.numSubordinates(dn), 13); |
| | | assertEquals(backend.numSubordinates(dn, false), 13); |
| | | assertEquals(backend.numSubordinates(dn, true), 13); |
| | | dn = DN.decode("dc=com"); |
| | | assertEquals(backend.numSubordinates(dn), -1); |
| | | assertEquals(backend.numSubordinates(dn, false), -1); |
| | | assertEquals(backend.numSubordinates(dn, true), -1); |
| | | dn = DN.decode("dc=test1,dc=com"); |
| | | assertEquals(backend.numSubordinates(dn), 2); |
| | | assertEquals(backend.numSubordinates(dn, false), 2); |
| | | assertEquals(backend.numSubordinates(dn, true), 2); |
| | | dn = DN.decode("uid=user.10,ou=People,dc=test,dc=com"); |
| | | assertEquals(backend.numSubordinates(dn), 0); |
| | | assertEquals(backend.numSubordinates(dn, false), 0); |
| | | assertEquals(backend.numSubordinates(dn, true), 0); |
| | | dn = DN.decode("uid=does not exist,ou=People,dc=test,dc=com"); |
| | | assertEquals(backend.numSubordinates(dn), -1); |
| | | assertEquals(backend.numSubordinates(dn, false), -1); |
| | | assertEquals(backend.numSubordinates(dn, true), -1); |
| | | } |
| | | |
| | | |