Fix issue 3446 and improve fix for issue 3726:
* introduce comprehensive unit test for checking
attribute filtering in search operations
* improvements to virtual attribute provider API
* improvements to virtual attribute processing
during Entry duplication
* fixes for bugs identified in new unit test.
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | * Copyright 2006-2009 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.api; |
| | | import org.opends.messages.Message; |
| | |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Collection; |
| | | import java.util.LinkedHashSet; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | |
| | | import org.opends.server.admin.std.server.VirtualAttributeCfg; |
| | | import org.opends.server.config.ConfigException; |
| | |
| | | |
| | | |
| | | /** |
| | | * Generates a set of values for the provided entry. |
| | | * Generates an unmodifiable set of values for the provided entry. |
| | | * |
| | | * @param entry The entry for which the values are to be |
| | | * generated. |
| | | * @param rule The virtual attribute rule which defines the |
| | | * constraints for the virtual attribute. |
| | | * |
| | | * @return The set of values generated for the provided entry. It |
| | | * may be empty, but it must not be {@code null}. |
| | | * @param entry |
| | | * The entry for which the values are to be generated. |
| | | * @param rule |
| | | * The virtual attribute rule which defines the constraints |
| | | * for the virtual attribute. |
| | | * @return The unmodifiable set of values generated for the provided |
| | | * entry. It may be empty, but it must not be {@code null}. |
| | | */ |
| | | public abstract LinkedHashSet<AttributeValue> |
| | | getValues(Entry entry, |
| | | VirtualAttributeRule rule); |
| | | public abstract Set<AttributeValue> getValues( |
| | | Entry entry, VirtualAttributeRule rule); |
| | | |
| | | |
| | | |
| | |
| | | public boolean hasAllValues(Entry entry, VirtualAttributeRule rule, |
| | | Collection<AttributeValue> values) |
| | | { |
| | | for (AttributeValue value : values) |
| | | { |
| | | if (! getValues(entry, rule).contains(value)) |
| | | { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | return true; |
| | | Set<AttributeValue> virtualValues = getValues(entry, rule); |
| | | return virtualValues.containsAll(values); |
| | | } |
| | | |
| | | |
| | |
| | | public boolean hasAnyValue(Entry entry, VirtualAttributeRule rule, |
| | | Collection<AttributeValue> values) |
| | | { |
| | | Set<AttributeValue> virtualValues = getValues(entry, rule); |
| | | for (AttributeValue value : values) |
| | | { |
| | | if (getValues(entry, rule).contains(value)) |
| | | if (virtualValues.contains(value)) |
| | | { |
| | | return true; |
| | | } |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | * Copyright 2006-2009 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.core; |
| | | |
| | |
| | | import java.util.LinkedHashSet; |
| | | import java.util.LinkedList; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | import java.util.concurrent.atomic.AtomicBoolean; |
| | | import org.opends.server.api.ClientConnection; |
| | | import org.opends.server.api.plugin.PluginResult; |
| | |
| | | // Make a copy of the entry and pare it down to only include the set |
| | | // of requested attributes. |
| | | Entry entryToReturn; |
| | | boolean omitReal = isVirtualAttributesOnly(); |
| | | boolean omitVirtual = isRealAttributesOnly(); |
| | | if ((getAttributes() == null) || getAttributes().isEmpty()) |
| | | { |
| | | entryToReturn = entry.duplicateWithoutOperationalAttributes(typesOnly, |
| | | true); |
| | | entryToReturn = |
| | | entry.duplicateWithoutOperationalAttributes(typesOnly, |
| | | omitReal, omitVirtual); |
| | | } |
| | | else |
| | | { |
| | |
| | | { |
| | | // This is a special placeholder indicating that all user attributes |
| | | // should be returned. |
| | | if (typesOnly) |
| | | if (!omitReal) |
| | | { |
| | | // First, add the placeholder for the objectclass attribute. |
| | | AttributeType ocType = |
| | | DirectoryServer.getObjectClassAttributeType(); |
| | | List<Attribute> ocList = new ArrayList<Attribute>(1); |
| | | ocList.add(Attributes.empty(ocType)); |
| | | entryToReturn.putAttribute(ocType, ocList); |
| | | } |
| | | else |
| | | { |
| | | // First, add the objectclass attribute. |
| | | Attribute ocAttr = entry.getObjectClassAttribute(); |
| | | if (ocAttr != null) |
| | | if (typesOnly) |
| | | { |
| | | entryToReturn.replaceAttribute(ocAttr); |
| | | // First, add the placeholder for the objectclass |
| | | // attribute. |
| | | AttributeType ocType = |
| | | DirectoryServer.getObjectClassAttributeType(); |
| | | List<Attribute> ocList = new ArrayList<Attribute>(1); |
| | | ocList.add(Attributes.empty(ocType)); |
| | | entryToReturn.putAttribute(ocType, ocList); |
| | | } |
| | | else |
| | | { |
| | | // First, add the objectclass attribute. |
| | | Attribute ocAttr = entry.getObjectClassAttribute(); |
| | | if (ocAttr != null) |
| | | { |
| | | entryToReturn.replaceAttribute(ocAttr); |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | for (AttributeType t : entry.getUserAttributes().keySet()) |
| | | { |
| | | List<Attribute> attrList = |
| | | entry.duplicateUserAttribute(t, null, typesOnly); |
| | | entryToReturn.putAttribute(t, attrList); |
| | | duplicateUserAttribute(entry, t, null, typesOnly, |
| | | omitReal, omitVirtual); |
| | | if (attrList != null) |
| | | { |
| | | entryToReturn.putAttribute(t, attrList); |
| | | } |
| | | } |
| | | |
| | | continue; |
| | |
| | | for (AttributeType t : entry.getOperationalAttributes().keySet()) |
| | | { |
| | | List<Attribute> attrList = |
| | | entry.duplicateOperationalAttribute(t, null, typesOnly); |
| | | entryToReturn.putAttribute(t, attrList); |
| | | duplicateOperationalAttribute(entry, t, null, |
| | | typesOnly, omitReal, omitVirtual); |
| | | if (attrList != null) |
| | | { |
| | | entryToReturn.putAttribute(t, attrList); |
| | | } |
| | | } |
| | | |
| | | continue; |
| | |
| | | semicolonPos = nextPos; |
| | | nextPos = attrName.indexOf(';', semicolonPos+1); |
| | | } |
| | | |
| | | options.add(attrName.substring(semicolonPos+1)); |
| | | } |
| | | else |
| | |
| | | options = null; |
| | | } |
| | | |
| | | |
| | | AttributeType attrType = DirectoryServer.getAttributeType(lowerName); |
| | | if (attrType == null) |
| | | { |
| | |
| | | if (t.hasNameOrOID(lowerName)) |
| | | { |
| | | List<Attribute> attrList = |
| | | entry.duplicateUserAttribute(t, options, typesOnly); |
| | | duplicateUserAttribute(entry, t, options, typesOnly, |
| | | omitReal, omitVirtual); |
| | | if (attrList != null) |
| | | { |
| | | entryToReturn.putAttribute(t, attrList); |
| | | |
| | | added = true; |
| | | break; |
| | | } |
| | |
| | | if (t.hasNameOrOID(lowerName)) |
| | | { |
| | | List<Attribute> attrList = |
| | | entry.duplicateOperationalAttribute(t, options, typesOnly); |
| | | duplicateOperationalAttribute(entry, t, options, |
| | | typesOnly, omitReal, omitVirtual); |
| | | if (attrList != null) |
| | | { |
| | | entryToReturn.putAttribute(t, attrList); |
| | | |
| | | break; |
| | | } |
| | | } |
| | |
| | | else |
| | | { |
| | | if (attrType.isObjectClassType()) { |
| | | if (typesOnly) |
| | | if (!omitReal) |
| | | { |
| | | AttributeType ocType = |
| | | DirectoryServer.getObjectClassAttributeType(); |
| | | List<Attribute> ocList = new ArrayList<Attribute>(1); |
| | | ocList.add(Attributes.empty(ocType)); |
| | | entryToReturn.putAttribute(ocType, ocList); |
| | | } |
| | | else |
| | | { |
| | | List<Attribute> attrList = new ArrayList<Attribute>(1); |
| | | attrList.add(entry.getObjectClassAttribute()); |
| | | entryToReturn.putAttribute(attrType, attrList); |
| | | if (typesOnly) |
| | | { |
| | | AttributeType ocType = |
| | | DirectoryServer.getObjectClassAttributeType(); |
| | | List<Attribute> ocList = new ArrayList<Attribute>(1); |
| | | ocList.add(Attributes.empty(ocType)); |
| | | entryToReturn.putAttribute(ocType, ocList); |
| | | } |
| | | else |
| | | { |
| | | List<Attribute> attrList = new ArrayList<Attribute>(1); |
| | | attrList.add(entry.getObjectClassAttribute()); |
| | | entryToReturn.putAttribute(attrType, attrList); |
| | | } |
| | | } |
| | | } |
| | | else |
| | | { |
| | | List<Attribute> attrList = |
| | | entry.duplicateOperationalAttribute(attrType, options, |
| | | typesOnly); |
| | | duplicateOperationalAttribute(entry, attrType, options, |
| | | typesOnly, omitReal, omitVirtual); |
| | | if (attrList == null) |
| | | { |
| | | attrList = entry.duplicateUserAttribute(attrType, options, |
| | | typesOnly); |
| | | attrList = |
| | | duplicateUserAttribute(entry, attrType, options, |
| | | typesOnly, omitReal, omitVirtual); |
| | | } |
| | | if (attrList != null) |
| | | { |
| | |
| | | } |
| | | } |
| | | |
| | | if (isRealAttributesOnly()) |
| | | { |
| | | entryToReturn.stripVirtualAttributes(); |
| | | } |
| | | else if (isVirtualAttributesOnly()) |
| | | { |
| | | entryToReturn.stripRealAttributes(); |
| | | } |
| | | |
| | | // If there is a matched values control, then further pare down the entry |
| | | // based on the filters that it contains. |
| | | MatchedValuesControl matchedValuesControl = getMatchedValuesControl(); |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public final void run() |
| | | { |
| | | setResultCode(ResultCode.UNDEFINED); |
| | |
| | | appendErrorMessage(message); |
| | | } |
| | | |
| | | |
| | | // Copies non-empty attributes. |
| | | private List<Attribute> duplicateAttribute( |
| | | List<Attribute> attrList, |
| | | Set<String> options, |
| | | boolean omitValues, |
| | | boolean omitReal, |
| | | boolean omitVirtual) |
| | | { |
| | | if (attrList == null) |
| | | { |
| | | return null; |
| | | } |
| | | |
| | | ArrayList<Attribute> duplicateList = |
| | | new ArrayList<Attribute>(attrList.size()); |
| | | for (Attribute a : attrList) |
| | | { |
| | | if (a.hasAllOptions(options)) |
| | | { |
| | | if (omitReal && !a.isVirtual()) |
| | | { |
| | | continue; |
| | | } |
| | | else if (omitVirtual && a.isVirtual()) |
| | | { |
| | | continue; |
| | | } |
| | | else if (a.isEmpty()) |
| | | { |
| | | continue; |
| | | } |
| | | else if (omitValues) |
| | | { |
| | | duplicateList.add(Attributes.empty(a)); |
| | | } |
| | | else |
| | | { |
| | | duplicateList.add(a); |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (duplicateList.isEmpty()) |
| | | { |
| | | return null; |
| | | } |
| | | else |
| | | { |
| | | return duplicateList; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | // Copy a user attribute - may return null if the attribute was |
| | | // not found or if it was empty. |
| | | private List<Attribute> duplicateUserAttribute( |
| | | Entry entry, |
| | | AttributeType attributeType, |
| | | Set<String> options, |
| | | boolean omitValues, |
| | | boolean omitReal, |
| | | boolean omitVirtual) |
| | | { |
| | | List<Attribute> currentList = entry.getUserAttribute(attributeType); |
| | | return duplicateAttribute(currentList, options, omitValues, |
| | | omitReal, omitVirtual); |
| | | } |
| | | |
| | | |
| | | |
| | | // Copy an operational attribute - may return null if the |
| | | // attribute was not found or if it was empty. |
| | | private List<Attribute> duplicateOperationalAttribute( |
| | | Entry entry, |
| | | AttributeType attributeType, |
| | | Set<String> options, |
| | | boolean omitValues, |
| | | boolean omitReal, |
| | | boolean omitVirtual) |
| | | { |
| | | List<Attribute> currentList = |
| | | entry.getOperationalAttribute(attributeType); |
| | | return duplicateAttribute(currentList, options, omitValues, |
| | | omitReal, omitVirtual); |
| | | } |
| | | } |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.extensions; |
| | | |
| | | |
| | | |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | import java.util.LinkedHashSet; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | |
| | | import org.opends.server.admin.std.server.EntryDNVirtualAttributeCfg; |
| | | import org.opends.server.api.VirtualAttributeProvider; |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public LinkedHashSet<AttributeValue> getValues(Entry entry, |
| | | VirtualAttributeRule rule) |
| | | public Set<AttributeValue> getValues(Entry entry, |
| | | VirtualAttributeRule rule) |
| | | { |
| | | LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>(1); |
| | | |
| | | String normDNString = entry.getDN().toNormalizedString(); |
| | | values.add(new AttributeValue(ByteStringFactory.create(normDNString), |
| | | ByteStringFactory.create(normDNString))); |
| | | |
| | | return values; |
| | | AttributeValue value = new AttributeValue( |
| | | ByteStringFactory.create(normDNString), |
| | | ByteStringFactory.create(normDNString)); |
| | | return Collections.singleton(value); |
| | | } |
| | | |
| | | |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.extensions; |
| | | |
| | | |
| | | |
| | | import java.util.LinkedHashSet; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | import java.util.UUID; |
| | | |
| | | import org.opends.messages.Message; |
| | |
| | | |
| | | import static org.opends.messages.ExtensionMessages.*; |
| | | import static org.opends.server.loggers.debug.DebugLogger.*; |
| | | import static org.opends.server.util.ServerConstants.*; |
| | | import static org.opends.server.util.StaticUtils.*; |
| | | |
| | | |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public LinkedHashSet<AttributeValue> getValues(Entry entry, |
| | | VirtualAttributeRule rule) |
| | | public Set<AttributeValue> getValues(Entry entry, |
| | | VirtualAttributeRule rule) |
| | | { |
| | | LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>(1); |
| | | |
| | | String normDNString = entry.getDN().toNormalizedString(); |
| | | String uuidString = |
| | | UUID.nameUUIDFromBytes(getBytes(normDNString)).toString(); |
| | | values.add(new AttributeValue(ByteStringFactory.create(uuidString), |
| | | ByteStringFactory.create(uuidString))); |
| | | |
| | | return values; |
| | | AttributeValue value = new AttributeValue( |
| | | ByteStringFactory.create(uuidString), |
| | | ByteStringFactory.create(uuidString)); |
| | | return Collections.singleton(value); |
| | | } |
| | | |
| | | |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.extensions; |
| | | |
| | | |
| | | |
| | | import java.util.LinkedHashSet; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | |
| | | import org.opends.messages.Message; |
| | | import org.opends.server.admin.std.server.HasSubordinatesVirtualAttributeCfg; |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public LinkedHashSet<AttributeValue> getValues(Entry entry, |
| | | VirtualAttributeRule rule) |
| | | public Set<AttributeValue> getValues(Entry entry, |
| | | VirtualAttributeRule rule) |
| | | { |
| | | LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>(1); |
| | | |
| | | Backend backend = DirectoryServer.getBackend(entry.getDN()); |
| | | |
| | | try |
| | |
| | | AttributeValue value = |
| | | new AttributeValue(ByteStringFactory.create(ret.toString()), |
| | | ByteStringFactory.create(ret.toString())); |
| | | values.add(value); |
| | | return Collections.singleton(value); |
| | | } |
| | | } |
| | | catch(DirectoryException de) |
| | |
| | | } |
| | | } |
| | | |
| | | return values; |
| | | return Collections.emptySet(); |
| | | } |
| | | |
| | | |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.extensions; |
| | | |
| | | |
| | | |
| | | import java.util.Collection; |
| | | import java.util.LinkedHashSet; |
| | | import java.util.Collections; |
| | | import java.util.HashSet; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | |
| | | import org.opends.server.admin.std.server.IsMemberOfVirtualAttributeCfg; |
| | | import org.opends.server.api.Group; |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public LinkedHashSet<AttributeValue> getValues(Entry entry, |
| | | VirtualAttributeRule rule) |
| | | public Set<AttributeValue> getValues(Entry entry, |
| | | VirtualAttributeRule rule) |
| | | { |
| | | // FIXME -- This probably isn't the most efficient implementation. |
| | | LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>(); |
| | | HashSet<AttributeValue> values = new HashSet<AttributeValue>(); |
| | | for (Group g : DirectoryServer.getGroupManager().getGroupInstances()) |
| | | { |
| | | try |
| | |
| | | } |
| | | } |
| | | |
| | | return values; |
| | | return Collections.unmodifiableSet(values); |
| | | } |
| | | |
| | | |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.extensions; |
| | | import org.opends.messages.Message; |
| | |
| | | |
| | | |
| | | import java.util.Collection; |
| | | import java.util.LinkedHashSet; |
| | | import java.util.Collections; |
| | | import java.util.HashSet; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | |
| | | import org.opends.server.admin.server.ConfigurationChangeListener; |
| | | import org.opends.server.admin.std.server.MemberVirtualAttributeCfg; |
| | |
| | | import org.opends.server.config.ConfigException; |
| | | import org.opends.server.core.DirectoryServer; |
| | | import org.opends.server.core.SearchOperation; |
| | | import org.opends.server.types.AttributeType; |
| | | import org.opends.server.types.AttributeValue; |
| | | import org.opends.server.types.ByteString; |
| | | import org.opends.server.types.ConditionResult; |
| | |
| | | |
| | | import static org.opends.server.loggers.debug.DebugLogger.*; |
| | | import org.opends.server.loggers.debug.DebugTracer; |
| | | import static org.opends.server.util.ServerConstants.*; |
| | | |
| | | |
| | | |
| | |
| | | */ |
| | | private static final DebugTracer TRACER = getTracer(); |
| | | |
| | | // The attribute type used to indicate which target group should be used to |
| | | // obtain the member list. |
| | | private AttributeType targetGroupType; |
| | | |
| | | // The current configuration for this member virtual attribute. |
| | | private MemberVirtualAttributeCfg currentConfig; |
| | | |
| | |
| | | { |
| | | configuration.addMemberChangeListener(this); |
| | | currentConfig = configuration; |
| | | |
| | | targetGroupType = |
| | | DirectoryServer.getAttributeType(ATTR_TARGET_GROUP_DN, true); |
| | | } |
| | | |
| | | |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public LinkedHashSet<AttributeValue> getValues(Entry entry, |
| | | VirtualAttributeRule rule) |
| | | public Set<AttributeValue> getValues(Entry entry, |
| | | VirtualAttributeRule rule) |
| | | { |
| | | if (! currentConfig.isAllowRetrievingMembership()) |
| | | { |
| | | return new LinkedHashSet<AttributeValue>(0); |
| | | return Collections.emptySet(); |
| | | } |
| | | |
| | | Group g = DirectoryServer.getGroupManager().getGroupInstance(entry.getDN()); |
| | | if (g == null) |
| | | { |
| | | return new LinkedHashSet<AttributeValue>(0); |
| | | return Collections.emptySet(); |
| | | } |
| | | |
| | | LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>(); |
| | | HashSet<AttributeValue> values = new HashSet<AttributeValue>(); |
| | | try |
| | | { |
| | | MemberList memberList = g.getMembers(); |
| | |
| | | } |
| | | } |
| | | |
| | | return values; |
| | | return Collections.unmodifiableSet(values); |
| | | } |
| | | |
| | | |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.extensions; |
| | | |
| | | |
| | | |
| | | import java.util.LinkedHashSet; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | |
| | | import org.opends.messages.Message; |
| | | import org.opends.server.admin.std.server.NumSubordinatesVirtualAttributeCfg; |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public LinkedHashSet<AttributeValue> getValues(Entry entry, |
| | | VirtualAttributeRule rule) |
| | | public Set<AttributeValue> getValues(Entry entry, |
| | | VirtualAttributeRule rule) |
| | | { |
| | | LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>(1); |
| | | |
| | | Backend backend = DirectoryServer.getBackend(entry.getDN()); |
| | | |
| | | try |
| | |
| | | AttributeValue value = |
| | | new AttributeValue(ByteStringFactory.create(String.valueOf(count)), |
| | | ByteStringFactory.create(String.valueOf(count))); |
| | | values.add(value); |
| | | return Collections.singleton(value); |
| | | } |
| | | } |
| | | catch(DirectoryException de) |
| | |
| | | } |
| | | } |
| | | |
| | | return values; |
| | | return Collections.emptySet(); |
| | | } |
| | | |
| | | |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | * Copyright 2006-2009 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.extensions; |
| | | |
| | | |
| | | |
| | | import java.util.LinkedHashSet; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | |
| | | import org.opends.messages.Message; |
| | | import org.opends.server.admin.std.server.SubschemaSubentryVirtualAttributeCfg; |
| | |
| | | import org.opends.server.config.ConfigException; |
| | | import org.opends.server.core.DirectoryServer; |
| | | import org.opends.server.core.SearchOperation; |
| | | import org.opends.server.loggers.debug.DebugTracer; |
| | | import org.opends.server.types.AttributeValue; |
| | | import org.opends.server.types.ByteString; |
| | | import org.opends.server.types.ConditionResult; |
| | |
| | | import org.opends.server.types.ResultCode; |
| | | import org.opends.server.types.VirtualAttributeRule; |
| | | |
| | | import static org.opends.server.loggers.debug.DebugLogger.*; |
| | | import static org.opends.messages.ExtensionMessages.*; |
| | | import static org.opends.server.util.ServerConstants.*; |
| | | |
| | | |
| | | |
| | |
| | | extends VirtualAttributeProvider<SubschemaSubentryVirtualAttributeCfg> |
| | | { |
| | | /** |
| | | * The tracer object for the debug logger. |
| | | */ |
| | | private static final DebugTracer TRACER = getTracer(); |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new instance of this subschemaSubentry virtual attribute |
| | | * provider. |
| | | */ |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public LinkedHashSet<AttributeValue> getValues(Entry entry, |
| | | VirtualAttributeRule rule) |
| | | public Set<AttributeValue> getValues(Entry entry, |
| | | VirtualAttributeRule rule) |
| | | { |
| | | LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>(1); |
| | | |
| | | values.add(new AttributeValue(rule.getAttributeType(), |
| | | DirectoryServer.getSchemaDN().toString())); |
| | | |
| | | return values; |
| | | AttributeValue value = |
| | | new AttributeValue(rule.getAttributeType(), |
| | | DirectoryServer.getSchemaDN().toString()); |
| | | return Collections.singleton(value); |
| | | } |
| | | |
| | | |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.extensions; |
| | | import org.opends.messages.Message; |
| | | |
| | | |
| | | |
| | | import java.util.LinkedHashSet; |
| | | import java.util.Collections; |
| | | import java.util.HashSet; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public LinkedHashSet<AttributeValue> getValues(Entry entry, |
| | | VirtualAttributeRule rule) |
| | | public Set<AttributeValue> getValues(Entry entry, |
| | | VirtualAttributeRule rule) |
| | | { |
| | | AttributeType attributeType = rule.getAttributeType(); |
| | | Set<String> userDefinedValues = currentConfig.getValue(); |
| | | |
| | | LinkedHashSet<AttributeValue> values = |
| | | new LinkedHashSet<AttributeValue>(userDefinedValues.size()); |
| | | for (String valueString : userDefinedValues) |
| | | { |
| | | values.add(new AttributeValue(attributeType, valueString)); |
| | | switch (userDefinedValues.size()) { |
| | | case 0: |
| | | return Collections.emptySet(); |
| | | case 1: |
| | | String valueString = userDefinedValues.iterator().next(); |
| | | AttributeValue value = new AttributeValue(attributeType, valueString); |
| | | return Collections.singleton(value); |
| | | default: |
| | | HashSet<AttributeValue> values = |
| | | new HashSet<AttributeValue>(userDefinedValues.size()); |
| | | for (String valueString2 : userDefinedValues) |
| | | { |
| | | values.add(new AttributeValue(attributeType, valueString2)); |
| | | } |
| | | return Collections.unmodifiableSet(values); |
| | | } |
| | | |
| | | return values; |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | private static final DebugTracer TRACER = getTracer(); |
| | | |
| | | // Indicates whether virtual attribute processing has been performed |
| | | // for this entry. |
| | | private boolean virtualAttributeProcessingPerformed; |
| | | |
| | | // The set of operational attributes for this entry. |
| | | private Map<AttributeType,List<Attribute>> operationalAttributes; |
| | | |
| | |
| | | private transient Object attachment; |
| | | |
| | | // The schema used to govern this entry. |
| | | private Schema schema; |
| | | private final Schema schema; |
| | | |
| | | |
| | | |
| | |
| | | { |
| | | attachment = null; |
| | | schema = DirectoryServer.getSchema(); |
| | | virtualAttributeProcessingPerformed = false; |
| | | |
| | | |
| | | suppressedAttributes = |
| | | new LinkedHashMap<AttributeType,List<Attribute>>(); |
| | | |
| | | |
| | | if (dn == null) |
| | | { |
| | | this.dn = DN.nullDN(); |
| | |
| | | |
| | | |
| | | /** |
| | | * Makes a copy of attributes matching the specified options. |
| | | * |
| | | * @param attrList The attributes to be copied. |
| | | * @param options The set of attribute options to include in |
| | | * matching elements. |
| | | * @param omitValues <CODE>true</CODE> if the values are to be |
| | | * omitted. |
| | | * |
| | | * @return A copy of the attributes matching the specified options, |
| | | * or <CODE>null</CODE> if there is no such attribute with |
| | | * the specified set of options. |
| | | */ |
| | | private static List<Attribute> duplicateAttribute( |
| | | List<Attribute> attrList, |
| | | Set<String> options, |
| | | boolean omitValues) |
| | | { |
| | | if (attrList == null) |
| | | { |
| | | return null; |
| | | } |
| | | |
| | | ArrayList<Attribute> duplicateList = |
| | | new ArrayList<Attribute>(attrList.size()); |
| | | for (Attribute a : attrList) |
| | | { |
| | | if (a.hasAllOptions(options)) |
| | | { |
| | | if (omitValues && !a.isVirtual()) |
| | | { |
| | | duplicateList.add(Attributes.empty(a)); |
| | | } |
| | | else |
| | | { |
| | | duplicateList.add(a); |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (duplicateList.isEmpty()) |
| | | { |
| | | return null; |
| | | } |
| | | else |
| | | { |
| | | return duplicateList; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves a copy of the requested user attribute element(s) for |
| | | * the specified attribute type. The list returned may include |
| | | * multiple elements if the same attribute exists in the entry |
| | | * multiple times with different sets of options. |
| | | * |
| | | * @param attributeType The attribute type to retrieve. |
| | | * @param options The set of attribute options to include in |
| | | * matching elements. |
| | | * @param omitValues <CODE>true</CODE> if the values are to be |
| | | * omitted. |
| | | * |
| | | * @return A copy of the requested attribute element(s) for the |
| | | * specified attribute type, or <CODE>null</CODE> if there |
| | | * is no such user attribute with the specified set of |
| | | * options. |
| | | */ |
| | | public List<Attribute> duplicateUserAttribute( |
| | | AttributeType attributeType, |
| | | Set<String> options, |
| | | boolean omitValues) |
| | | { |
| | | List<Attribute> currentList = getUserAttribute(attributeType); |
| | | return duplicateAttribute(currentList, options, omitValues); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves a copy of the requested operational attribute |
| | | * element(s) for the specified attribute type. The list returned |
| | | * may include multiple elements if the same attribute exists in |
| | | * the entry multiple times with different sets of options. |
| | | * |
| | | * @param attributeType The attribute type to retrieve. |
| | | * @param options The set of attribute options to include in |
| | | * matching elements. |
| | | * @param omitValues <CODE>true</CODE> if the values are to be |
| | | * omitted. |
| | | * |
| | | * @return A copy of the requested attribute element(s) for the |
| | | * specified attribute type, or <CODE>null</CODE> if there |
| | | * is no such user attribute with the specified set of |
| | | * options. |
| | | */ |
| | | public List<Attribute> duplicateOperationalAttribute( |
| | | AttributeType attributeType, |
| | | Set<String> options, |
| | | boolean omitValues) |
| | | { |
| | | List<Attribute> currentList = |
| | | getOperationalAttribute(attributeType); |
| | | return duplicateAttribute(currentList, options, omitValues); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Indicates whether this entry contains the specified operational |
| | | * attribute. |
| | | * |
| | |
| | | HashMap<AttributeType,List<Attribute>> userAttrsCopy = |
| | | new HashMap<AttributeType,List<Attribute>>( |
| | | userAttributes.size()); |
| | | deepCopy(userAttributes, userAttrsCopy, false); |
| | | deepCopy(userAttributes, userAttrsCopy, false, false, false, |
| | | true); |
| | | |
| | | HashMap<AttributeType,List<Attribute>> operationalAttrsCopy = |
| | | new HashMap<AttributeType,List<Attribute>>( |
| | | operationalAttributes.size()); |
| | | deepCopy(operationalAttributes, operationalAttrsCopy, false); |
| | | deepCopy(operationalAttributes, operationalAttrsCopy, false, |
| | | false, false, true); |
| | | |
| | | for (AttributeType t : suppressedAttributes.keySet()) |
| | | { |
| | |
| | | |
| | | /** |
| | | * Creates a duplicate of this entry without any operational |
| | | * attributes that may be altered without impacting the information |
| | | * in this entry. |
| | | * attributes that may be altered without impacting the |
| | | * information in this entry. |
| | | * <p> |
| | | * TODO: this method is very specific to search result |
| | | * processing but we are forced to have it here due to tight |
| | | * coupling and performance reasons. |
| | | * |
| | | * @param typesOnly Indicates whether to include attribute |
| | | * types only without values. |
| | | * @param processVirtual Indicates whether virtual attribute |
| | | * processing should be performed for the |
| | | * entry. |
| | | * |
| | | * @return A duplicate of this entry that may be altered without |
| | | * impacting the information in this entry and that does |
| | | * not contain any operational attributes. |
| | | * @param typesOnly |
| | | * Indicates whether to include attribute types only |
| | | * without values. |
| | | * @param omitReal |
| | | * Indicates whether to exclude real attributes. |
| | | * @param omitVirtual |
| | | * Indicates whether to exclude virtual attributes. |
| | | * @return A duplicate of this entry that may be altered without |
| | | * impacting the information in this entry and that does not |
| | | * contain any operational attributes. |
| | | */ |
| | | public Entry duplicateWithoutOperationalAttributes( |
| | | boolean typesOnly, boolean processVirtual) |
| | | boolean typesOnly, boolean omitReal, boolean omitVirtual) |
| | | { |
| | | HashMap<ObjectClass,String> objectClassesCopy; |
| | | if (typesOnly) |
| | | if (typesOnly || omitReal) |
| | | { |
| | | objectClassesCopy = new HashMap<ObjectClass,String>(0); |
| | | } |
| | |
| | | HashMap<AttributeType,List<Attribute>> userAttrsCopy = |
| | | new HashMap<AttributeType,List<Attribute>>( |
| | | userAttributes.size()); |
| | | if (typesOnly) |
| | | |
| | | if (typesOnly && !omitReal) |
| | | { |
| | | // Make sure to include the objectClass attribute here because |
| | | // it won't make it in otherwise. |
| | |
| | | userAttrsCopy.put(ocType, ocList); |
| | | } |
| | | |
| | | deepCopy(userAttributes, userAttrsCopy, typesOnly); |
| | | deepCopy(userAttributes, userAttrsCopy, typesOnly, true, |
| | | omitReal, omitVirtual); |
| | | |
| | | HashMap<AttributeType,List<Attribute>> operationalAttrsCopy = |
| | | new HashMap<AttributeType,List<Attribute>>(0); |
| | | |
| | | for (AttributeType t : suppressedAttributes.keySet()) |
| | | { |
| | | List<Attribute> attrList = suppressedAttributes.get(t); |
| | | if (! t.isOperational()) |
| | | { |
| | | userAttributes.put(t, attrList); |
| | | } |
| | | } |
| | | |
| | | Entry e = new Entry(dn, objectClassesCopy, userAttrsCopy, |
| | | operationalAttrsCopy); |
| | | |
| | | if (processVirtual) |
| | | { |
| | | e.processVirtualAttributes(false); |
| | | } |
| | | |
| | | return e; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Performs a deep copy from the source map to the target map. In |
| | | * this case, the attributes in the list will be duplicates rather |
| | | * than re-using the same reference. Virtual attributes will not be |
| | | * included when making the copy. |
| | | * Performs a deep copy from the source map to the target map. |
| | | * In this case, the attributes in the list will be duplicates |
| | | * rather than re-using the same reference. |
| | | * |
| | | * @param source The source map from which to obtain the |
| | | * information. |
| | | * @param target The target map into which to place the |
| | | * copied information. |
| | | * @param omitValues Indicates whether to omit attribute values |
| | | * when processing. |
| | | * @param source |
| | | * The source map from which to obtain the information. |
| | | * @param target |
| | | * The target map into which to place the copied |
| | | * information. |
| | | * @param omitValues |
| | | * Indicates whether to omit attribute values when |
| | | * processing. |
| | | * @param omitEmpty |
| | | * Indicates whether to omit empty attributes when |
| | | * processing. |
| | | * @param omitReal |
| | | * Indicates whether to exclude real attributes. |
| | | * @param omitVirtual |
| | | * Indicates whether to exclude virtual attributes. |
| | | */ |
| | | private void deepCopy(Map<AttributeType,List<Attribute>> source, |
| | | Map<AttributeType,List<Attribute>> target, |
| | | boolean omitValues) |
| | | boolean omitValues, |
| | | boolean omitEmpty, |
| | | boolean omitReal, |
| | | boolean omitVirtual) |
| | | { |
| | | for (AttributeType t : source.keySet()) |
| | | { |
| | |
| | | |
| | | for (Attribute a : sourceList) |
| | | { |
| | | if (a.isVirtual()) |
| | | if (omitReal && !a.isVirtual()) |
| | | { |
| | | continue; |
| | | } |
| | | |
| | | if (omitValues) |
| | | else if (omitVirtual && a.isVirtual()) |
| | | { |
| | | continue; |
| | | } |
| | | else if (omitEmpty && a.isEmpty()) |
| | | { |
| | | continue; |
| | | } |
| | | else if (omitValues) |
| | | { |
| | | targetList.add(Attributes.empty(a)); |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | if (! targetList.isEmpty()) |
| | | if (!targetList.isEmpty()) |
| | | { |
| | | target.put(t, targetList); |
| | | } |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | virtualAttributeProcessingPerformed = true; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether virtual attribute processing has been performed |
| | | * for this entry. |
| | | * |
| | | * @return {@code true} if virtual attribute processing has been |
| | | * performed for this entry, or {@code false} if not. |
| | | */ |
| | | public boolean virtualAttributeProcessingPerformed() |
| | | { |
| | | return virtualAttributeProcessingPerformed; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Strips out all real attributes from this entry so that it only |
| | | * contains virtual attributes. |
| | | */ |
| | | public void stripRealAttributes() |
| | | { |
| | | // The objectClass attribute will always be a real attribute. |
| | | objectClasses.clear(); |
| | | |
| | | Iterator<Map.Entry<AttributeType,List<Attribute>>> |
| | | attrListIterator = userAttributes.entrySet().iterator(); |
| | | while (attrListIterator.hasNext()) |
| | | { |
| | | Map.Entry<AttributeType,List<Attribute>> mapEntry = |
| | | attrListIterator.next(); |
| | | Iterator<Attribute> attrIterator = |
| | | mapEntry.getValue().iterator(); |
| | | while (attrIterator.hasNext()) |
| | | { |
| | | Attribute a = attrIterator.next(); |
| | | if (! a.isVirtual()) |
| | | { |
| | | attrIterator.remove(); |
| | | } |
| | | } |
| | | |
| | | if (mapEntry.getValue().isEmpty()) |
| | | { |
| | | attrListIterator.remove(); |
| | | } |
| | | } |
| | | |
| | | attrListIterator = operationalAttributes.entrySet().iterator(); |
| | | while (attrListIterator.hasNext()) |
| | | { |
| | | Map.Entry<AttributeType,List<Attribute>> mapEntry = |
| | | attrListIterator.next(); |
| | | Iterator<Attribute> attrIterator = |
| | | mapEntry.getValue().iterator(); |
| | | while (attrIterator.hasNext()) |
| | | { |
| | | Attribute a = attrIterator.next(); |
| | | if (! a.isVirtual()) |
| | | { |
| | | attrIterator.remove(); |
| | | } |
| | | } |
| | | |
| | | if (mapEntry.getValue().isEmpty()) |
| | | { |
| | | attrListIterator.remove(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Strips out all virtual attributes from this entry so that it only |
| | | * contains real attributes. |
| | | */ |
| | | public void stripVirtualAttributes() |
| | | { |
| | | Iterator<Map.Entry<AttributeType,List<Attribute>>> |
| | | attrListIterator = userAttributes.entrySet().iterator(); |
| | | while (attrListIterator.hasNext()) |
| | | { |
| | | Map.Entry<AttributeType,List<Attribute>> mapEntry = |
| | | attrListIterator.next(); |
| | | Iterator<Attribute> attrIterator = |
| | | mapEntry.getValue().iterator(); |
| | | while (attrIterator.hasNext()) |
| | | { |
| | | Attribute a = attrIterator.next(); |
| | | if (a.isVirtual()) |
| | | { |
| | | attrIterator.remove(); |
| | | } |
| | | } |
| | | |
| | | if (mapEntry.getValue().isEmpty()) |
| | | { |
| | | attrListIterator.remove(); |
| | | } |
| | | } |
| | | |
| | | attrListIterator = operationalAttributes.entrySet().iterator(); |
| | | while (attrListIterator.hasNext()) |
| | | { |
| | | Map.Entry<AttributeType,List<Attribute>> mapEntry = |
| | | attrListIterator.next(); |
| | | Iterator<Attribute> attrIterator = |
| | | mapEntry.getValue().iterator(); |
| | | while (attrIterator.hasNext()) |
| | | { |
| | | Attribute a = attrIterator.next(); |
| | | if (a.isVirtual()) |
| | | { |
| | | attrIterator.remove(); |
| | | } |
| | | } |
| | | |
| | | if (mapEntry.getValue().isEmpty()) |
| | | { |
| | | attrListIterator.remove(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | * |
| | | * @return A string representation of this protocol element. |
| | | */ |
| | | @Override |
| | | public String toString() |
| | | { |
| | | StringBuilder buffer = new StringBuilder(); |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.types; |
| | | |
| | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the entry in which this virtual attribute exists. |
| | | * |
| | | * @return The entry in which this virtual attribute exists. |
| | | */ |
| | | public Entry getEntry() |
| | | { |
| | | return entry; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | |
| | | public Iterator<AttributeValue> iterator() |
| | | { |
| | | Set<AttributeValue> values = provider.getValues(entry, rule); |
| | | return Collections.unmodifiableSet(values).iterator(); |
| | | return values.iterator(); |
| | | } |
| | | |
| | | |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | * Copyright 2006-2009 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.opends.server.core; |
| | |
| | | import org.opends.server.protocols.ldap.*; |
| | | import org.opends.server.types.*; |
| | | import org.opends.server.TestCaseUtils; |
| | | import org.opends.server.util.ServerConstants; |
| | | import org.opends.server.util.StaticUtils; |
| | | import org.opends.server.controls.MatchedValuesFilter; |
| | | import org.opends.server.controls.MatchedValuesControl; |
| | | import org.opends.server.plugins.InvocationCounterPlugin; |
| | | import org.testng.annotations.BeforeClass; |
| | | import org.testng.annotations.DataProvider; |
| | | import org.testng.annotations.Test; |
| | | import static org.testng.Assert.assertEquals; |
| | | import static org.testng.Assert.assertNotNull; |
| | | import static org.testng.Assert.assertTrue; |
| | | import static org.testng.Assert.*; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Arrays; |
| | | import java.util.LinkedHashSet; |
| | | import java.util.LinkedList; |
| | | import java.util.List; |
| | | import java.net.Socket; |
| | | import java.io.IOException; |
| | |
| | | Entry resultEntry = searchInternalForSingleEntry(searchOperation); |
| | | |
| | | assertEquals(resultEntry.getObjectClasses().size(), 0); |
| | | |
| | | assertEquals(resultEntry.getUserAttributes().size(), |
| | | testEntry.getUserAttributes().size() + 1); |
| | | assertEquals(resultEntry.getOperationalAttributes().size(), 0); |
| | |
| | | assertEquals(searchOperation.getResultCode(), ResultCode.NO_SUCH_OBJECT); |
| | | assertNotNull(searchOperation.getMatchedDN()); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Determines how attributes should be filtered in search operations. |
| | | */ |
| | | private enum AttributeFilterType { |
| | | DEFAULT, WILDCARDS, ENUMERATED; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns test data for testSearchInternalAttributeFilters. |
| | | * |
| | | * @return The test data. |
| | | */ |
| | | @DataProvider(name = "testSearchInternalAttributeFilters") |
| | | public Object[][] createTestSearchInternalAttributeFiltersData() |
| | | { |
| | | // It was quicker to cut n paste... |
| | | return new Object[][] { |
| | | {AttributeFilterType.DEFAULT, false, false, false}, |
| | | {AttributeFilterType.DEFAULT, false, false, true}, |
| | | {AttributeFilterType.DEFAULT, false, true, false}, |
| | | {AttributeFilterType.DEFAULT, false, true, true}, |
| | | {AttributeFilterType.DEFAULT, true, false, false}, |
| | | {AttributeFilterType.DEFAULT, true, false, true}, |
| | | {AttributeFilterType.DEFAULT, true, true, false}, |
| | | {AttributeFilterType.DEFAULT, true, true, true}, |
| | | {AttributeFilterType.WILDCARDS, false, false, false}, |
| | | {AttributeFilterType.WILDCARDS, false, false, true}, |
| | | {AttributeFilterType.WILDCARDS, false, true, false}, |
| | | {AttributeFilterType.WILDCARDS, false, true, true}, |
| | | {AttributeFilterType.WILDCARDS, true, false, false}, |
| | | {AttributeFilterType.WILDCARDS, true, false, true}, |
| | | {AttributeFilterType.WILDCARDS, true, true, false}, |
| | | {AttributeFilterType.WILDCARDS, true, true, true}, |
| | | {AttributeFilterType.ENUMERATED, false, false, false}, |
| | | {AttributeFilterType.ENUMERATED, false, false, true}, |
| | | {AttributeFilterType.ENUMERATED, false, true, false}, |
| | | {AttributeFilterType.ENUMERATED, false, true, true}, |
| | | {AttributeFilterType.ENUMERATED, true, false, false}, |
| | | {AttributeFilterType.ENUMERATED, true, false, true}, |
| | | {AttributeFilterType.ENUMERATED, true, true, false}, |
| | | {AttributeFilterType.ENUMERATED, true, true, true}, |
| | | }; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests that attribute filtering is performed correctly for real and |
| | | * virtual attributes when various combinations of typesOnly, and the |
| | | * real-attributes-only and virtual-attributes-only controls are used |
| | | * (issues 3446 and 3726). |
| | | * |
| | | * @param filterType |
| | | * Specifies how attributes should be filtered. |
| | | * @param typesOnly |
| | | * Strip attribute values. |
| | | * @param stripVirtualAttributes |
| | | * Strip virtual attributes. |
| | | * @param stripRealAttributes |
| | | * Strip real attributes. |
| | | * @throws Exception |
| | | * If an unexpected problem occurs. |
| | | */ |
| | | @Test(dataProvider = "testSearchInternalAttributeFilters") |
| | | public void testSearchInternalAttributeFilters( |
| | | AttributeFilterType filterType, boolean typesOnly, |
| | | boolean stripVirtualAttributes, boolean stripRealAttributes) |
| | | throws Exception |
| | | { |
| | | TestCaseUtils.initializeTestBackend(true); |
| | | |
| | | // Real attributes (these are all user attributes). |
| | | List<String> realAttrTypes = |
| | | Arrays.asList("objectclass", "uid", "cn", "sn", "givenname", |
| | | "userpassword"); |
| | | |
| | | // Virtual attributes (these are all operational attributes). |
| | | List<String> virtualAttrTypes = |
| | | Arrays.asList("numsubordinates", "hassubordinates", |
| | | "subschemasubentry", "entrydn", "ismemberof"); |
| | | |
| | | String userDNString = "uid=test.user,o=test"; |
| | | DN userDN = DN.decode(userDNString); |
| | | |
| | | TestCaseUtils.addEntry("dn: " + userDNString, |
| | | "objectClass: top", |
| | | "objectClass: person", |
| | | "objectClass: organizationalPerson", |
| | | "objectClass: inetOrgPerson", |
| | | "uid: test.user", |
| | | "givenName: Test", |
| | | "sn: User", |
| | | "cn: Test User", |
| | | "userPassword: password"); |
| | | |
| | | Entry userEntry = DirectoryServer.getEntry(userDN); |
| | | assertNotNull(userEntry); |
| | | |
| | | LinkedHashSet<String> attributes = new LinkedHashSet<String>(); |
| | | switch (filterType) |
| | | { |
| | | case DEFAULT: |
| | | // Only user attributes. |
| | | attributes = null; |
| | | break; |
| | | case WILDCARDS: |
| | | attributes.add("*"); |
| | | attributes.add("+"); |
| | | break; |
| | | case ENUMERATED: |
| | | attributes.addAll(realAttrTypes); |
| | | attributes.addAll(virtualAttrTypes); |
| | | break; |
| | | } |
| | | |
| | | List<Control> controls = new LinkedList<Control>(); |
| | | |
| | | if (stripRealAttributes) |
| | | { |
| | | controls.add(new Control(ServerConstants.OID_VIRTUAL_ATTRS_ONLY, |
| | | false)); |
| | | } |
| | | |
| | | if (stripVirtualAttributes) |
| | | { |
| | | controls.add(new Control(ServerConstants.OID_REAL_ATTRS_ONLY, |
| | | false)); |
| | | } |
| | | |
| | | InternalClientConnection conn = |
| | | InternalClientConnection.getRootConnection(); |
| | | |
| | | InternalSearchOperation search = |
| | | conn.processSearch(userDNString, SearchScope.BASE_OBJECT, |
| | | DereferencePolicy.NEVER_DEREF_ALIASES, 0, // Size limit |
| | | 0, // Time limit |
| | | typesOnly, // Types only |
| | | "(objectClass=*)", attributes, controls, null); |
| | | |
| | | assertEquals(search.getResultCode(), ResultCode.SUCCESS); |
| | | |
| | | LinkedList<SearchResultEntry> entries = search.getSearchEntries(); |
| | | assertEquals(entries.size(), 1); |
| | | |
| | | Entry entry = entries.getFirst(); |
| | | assertEquals(entry.getDN(), userDN); |
| | | |
| | | // Check real attributes. |
| | | List<String> messages = new LinkedList<String>(); |
| | | for (String attrType : realAttrTypes) |
| | | { |
| | | List<Attribute> attrList = entry.getAttribute(attrType); |
| | | |
| | | if (stripRealAttributes) |
| | | { |
| | | if (attrList != null) |
| | | { |
| | | messages.add("Unexpected real attribute: " + attrType); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | if (attrList == null) |
| | | { |
| | | messages.add("Missing real attribute: " + attrType); |
| | | } |
| | | else |
| | | { |
| | | Attribute attr = attrList.get(0); |
| | | if (typesOnly) |
| | | { |
| | | if (!attr.isEmpty()) |
| | | { |
| | | messages.add("Unexpected non-empty real attribute: " |
| | | + attrType); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | if (attr.isEmpty()) |
| | | { |
| | | messages.add("Unexpected empty real attribute: " |
| | | + attrType); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // Check virtual (operational) attributes. |
| | | for (String attrType : virtualAttrTypes) |
| | | { |
| | | List<Attribute> attrList = entry.getAttribute(attrType); |
| | | |
| | | if (stripVirtualAttributes) |
| | | { |
| | | if (attrList != null) |
| | | { |
| | | messages.add("Unexpected virtual attribute: " + attrType); |
| | | } |
| | | } |
| | | else if (filterType == AttributeFilterType.DEFAULT) |
| | | { |
| | | if (attrList != null) |
| | | { |
| | | messages.add("Unexpected operational attribute: " + attrType); |
| | | } |
| | | } |
| | | else if (attrType.equals("ismemberof")) |
| | | { |
| | | // isMemberOf should never be returned as user is not in any |
| | | // groups. |
| | | if (attrList != null) |
| | | { |
| | | messages.add("Unexpected isMemberOf attribute"); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | if (attrList == null) |
| | | { |
| | | messages.add("Missing virtual attribute: " + attrType); |
| | | } |
| | | else |
| | | { |
| | | Attribute attr = attrList.get(0); |
| | | if (typesOnly) |
| | | { |
| | | if (!attr.isEmpty()) |
| | | { |
| | | messages.add("Unexpected non-empty virtual attribute: " |
| | | + attrType); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | if (attr.isEmpty()) |
| | | { |
| | | messages.add("Unexpected empty virtual attribute: " |
| | | + attrType); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | assertTrue(messages.isEmpty(), "Entry invalid: " + messages); |
| | | } |
| | | } |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.extensions; |
| | | |
| | |
| | | import java.util.LinkedHashSet; |
| | | import java.util.LinkedList; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | |
| | | import org.testng.annotations.BeforeClass; |
| | | import org.testng.annotations.DataProvider; |
| | |
| | | VirtualAttributeCfgDefn.ConflictBehavior. |
| | | VIRTUAL_OVERRIDES_REAL); |
| | | |
| | | LinkedHashSet<AttributeValue> values = provider.getValues(entry, rule); |
| | | Set<AttributeValue> values = provider.getValues(entry, rule); |
| | | assertNotNull(values); |
| | | assertEquals(values.size(), 1); |
| | | assertTrue(values.contains(new AttributeValue(entryDNType, "o=test"))); |
| | |
| | | 0, false, filter, null, null); |
| | | LocalBackendSearchOperation localSearch = |
| | | new LocalBackendSearchOperation(searchOperation); |
| | | |
| | | |
| | | provider.processSearch(rule, localSearch); |
| | | |
| | | if (shouldMatch) |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.extensions; |
| | | |
| | |
| | | import java.util.LinkedHashSet; |
| | | import java.util.LinkedList; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | import java.util.UUID; |
| | | |
| | | import org.testng.annotations.BeforeClass; |
| | |
| | | VirtualAttributeCfgDefn.ConflictBehavior. |
| | | VIRTUAL_OVERRIDES_REAL); |
| | | |
| | | LinkedHashSet<AttributeValue> values = provider.getValues(entry, rule); |
| | | Set<AttributeValue> values = provider.getValues(entry, rule); |
| | | assertNotNull(values); |
| | | assertEquals(values.size(), 1); |
| | | assertTrue(values.contains(new AttributeValue(entryUUIDType, uuidString))); |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.extensions; |
| | | |
| | |
| | | import java.util.Collections; |
| | | import java.util.LinkedHashSet; |
| | | import java.util.LinkedList; |
| | | import java.util.List; |
| | | |
| | | import org.testng.annotations.BeforeClass; |
| | | import org.testng.annotations.DataProvider; |
| | |
| | | import org.opends.server.types.ByteString; |
| | | import org.opends.server.types.ByteStringFactory; |
| | | import org.opends.server.types.ConditionResult; |
| | | import org.opends.server.types.Control; |
| | | import org.opends.server.types.DereferencePolicy; |
| | | import org.opends.server.types.DN; |
| | | import org.opends.server.types.Entry; |
| | |
| | | |
| | | import static org.testng.Assert.*; |
| | | |
| | | import static org.opends.server.util.ServerConstants.*; |
| | | |
| | | |
| | | |
| | | /** |
| | |
| | | InternalClientConnection conn = |
| | | InternalClientConnection.getRootConnection(); |
| | | InternalSearchOperation searchOperation = |
| | | new InternalSearchOperation(conn, conn.nextOperationID(), |
| | | conn.nextMessageID(), null, |
| | | new InternalSearchOperation(conn, |
| | | InternalClientConnection.nextOperationID(), |
| | | InternalClientConnection.nextMessageID(), |
| | | null, |
| | | DN.decode("o=test"), |
| | | SearchScope.WHOLE_SUBTREE, |
| | | DereferencePolicy.NEVER_DEREF_ALIASES, 0, |
| | |
| | | InternalClientConnection conn = |
| | | InternalClientConnection.getRootConnection(); |
| | | InternalSearchOperation searchOperation = |
| | | new InternalSearchOperation(conn, conn.nextOperationID(), |
| | | conn.nextMessageID(), null, |
| | | new InternalSearchOperation(conn, |
| | | InternalClientConnection.nextOperationID(), |
| | | InternalClientConnection.nextMessageID(), |
| | | null, |
| | | DN.decode("o=test"), |
| | | SearchScope.WHOLE_SUBTREE, |
| | | DereferencePolicy.NEVER_DEREF_ALIASES, 0, |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.extensions; |
| | | |
| | |
| | | import java.util.LinkedHashSet; |
| | | import java.util.LinkedList; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | |
| | | import org.testng.annotations.BeforeClass; |
| | | import org.testng.annotations.DataProvider; |
| | |
| | | import org.opends.server.types.Attribute; |
| | | import org.opends.server.types.AttributeType; |
| | | import org.opends.server.types.AttributeValue; |
| | | import org.opends.server.types.ByteString; |
| | | import org.opends.server.types.ByteStringFactory; |
| | | import org.opends.server.types.ConditionResult; |
| | | import org.opends.server.types.Control; |
| | | import org.opends.server.types.DereferencePolicy; |
| | | import org.opends.server.types.DN; |
| | |
| | | VirtualAttributeCfgDefn.ConflictBehavior. |
| | | VIRTUAL_OVERRIDES_REAL); |
| | | |
| | | LinkedHashSet<AttributeValue> values = provider.getValues(entry, rule); |
| | | Set<AttributeValue> values = provider.getValues(entry, rule); |
| | | assertNotNull(values); |
| | | assertEquals(values.size(), 1); |
| | | assertTrue(values.contains(new AttributeValue(subschemaSubentryType, |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.extensions; |
| | | |
| | |
| | | import java.util.LinkedHashSet; |
| | | import java.util.LinkedList; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | |
| | | import org.testng.annotations.BeforeClass; |
| | | import org.testng.annotations.DataProvider; |
| | |
| | | |
| | | assertTrue(provider.isMultiValued()); |
| | | |
| | | LinkedHashSet<AttributeValue> values = provider.getValues(entry, rule); |
| | | Set<AttributeValue> values = provider.getValues(entry, rule); |
| | | assertNotNull(values); |
| | | assertFalse(values.isEmpty()); |
| | | assertTrue(provider.hasValue(entry, rule)); |
| | |
| | | |
| | | assertTrue(provider.isMultiValued()); |
| | | |
| | | LinkedHashSet<AttributeValue> values = provider.getValues(entry, rule); |
| | | Set<AttributeValue> values = provider.getValues(entry, rule); |
| | | assertNotNull(values); |
| | | assertTrue(values.isEmpty()); |
| | | assertFalse(provider.hasValue(entry, rule)); |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.types; |
| | | |
| | |
| | | public void testGetters() |
| | | throws Exception |
| | | { |
| | | assertNotNull(virtualAttribute.getEntry()); |
| | | assertEquals(virtualAttribute.getEntry().getDN(), |
| | | DN.decode("o=test")); |
| | | |
| | | assertEquals(virtualAttribute.getVirtualAttributeRule(), |
| | | virtualAttributeRule); |
| | | |