<commit_before>package edu.psu.swe.scim.server.utility;

import java.lang.reflect.Field;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Function;

import javax.ejb.Stateless;
import javax.inject.Inject;

import org.apache.commons.lang3.StringUtils;

import edu.psu.swe.scim.server.exception.AttributeDoesNotExistException;
import edu.psu.swe.scim.server.schema.Registry;
import edu.psu.swe.scim.spec.protocol.attribute.AttributeReference;
import edu.psu.swe.scim.spec.resources.ScimGroup;
import edu.psu.swe.scim.spec.resources.ScimResource;
import edu.psu.swe.scim.spec.resources.ScimUser;
import edu.psu.swe.scim.spec.schema.AttributeContainer;
import edu.psu.swe.scim.spec.schema.Schema;
import edu.psu.swe.scim.spec.schema.Schema.Attribute;
import edu.psu.swe.scim.spec.schema.Schema.Attribute.Returned;
import edu.psu.swe.scim.spec.schema.Schema.Attribute.Type;
import lombok.extern.slf4j.Slf4j;

@Stateless
@Slf4j
public class AttributeUtil {

  @Inject
  Registry registry;

  public <T extends ScimResource> T setAttributesForDisplay(T resource) throws IllegalArgumentException, IllegalAccessException, AttributeDoesNotExistException {
    String resourceType = resource.getResourceType();
    Schema schema = registry.getBaseSchemaOfResourceType(resourceType);

    // return always and default, exclude never and requested
    removeAttributesOfType(resource, schema, Returned.REQUEST);
    removeAttributesOfType(resource, schema, Returned.NEVER);
    return resource;
  }
  
  public <T extends ScimResource> T setAttributesForDisplay(T resource, Set<AttributeReference> attributes) throws IllegalArgumentException, IllegalAccessException, AttributeDoesNotExistException {
    if (attributes.isEmpty()) {
      return setAttributesForDisplay(resource);
    } else {
      String resourceType = resource.getResourceType();
      Schema schema = registry.getBaseSchemaOfResourceType(resourceType);

      // return always and specified attributes, exclude never
      log.debug(" ### Resolve attribute reference");
      Set<Attribute> attributesToKeep = resolveAttributeReferences(attributes);
      log.debug(" ### Remove attributes of type default");
      removeAttributesOfType(resource, schema, Returned.DEFAULT, attributesToKeep);
      log.debug(" ### Remove attributes of type request");
      removeAttributesOfType(resource, schema, Returned.REQUEST, attributesToKeep);
      log.debug(" ### Remove attributes of type never");
      removeAttributesOfType(resource, schema, Returned.NEVER, attributesToKeep);
    }

    return resource;
  }

  public <T extends ScimResource> T setExcludedAttributesForDisplay(T resource, Set<AttributeReference> excludedAttributes) throws IllegalArgumentException, IllegalAccessException, AttributeDoesNotExistException {
   
    if (excludedAttributes.isEmpty()) {
      return setAttributesForDisplay(resource);
    } else {
      String resourceType = resource.getResourceType();
      Schema schema = registry.getBaseSchemaOfResourceType(resourceType);

      // return always and default, exclude never and specified attributes
      Set<Attribute> attributesToRemove = resolveAttributeReferences(excludedAttributes);
      removeAttributesOfType(resource, schema, Returned.REQUEST);
      removeAttributesOfType(resource, schema, Returned.NEVER);
      removeAttributes(resource, schema, attributesToRemove);
    }

    return resource;
  }

  private void removeAttributesOfType(Object object, AttributeContainer attributeContainer, Returned returned) throws IllegalArgumentException, IllegalAccessException {
    Function<Attribute, Boolean> function = (attribute) -> returned == attribute.getReturned();
    processAttributes(object, attributeContainer, function);
  }

  private void removeAttributesOfType(Object object, AttributeContainer attributeContainer, Returned returned, Set<Attribute> attributesToKeep) throws IllegalArgumentException, IllegalAccessException {
    Function<Attribute, Boolean> function = (attribute) -> !attributesToKeep.contains(attribute) && returned == attribute.getReturned();
    processAttributes(object, attributeContainer, function);
  }
  
  private void removeAttributes(Object object, AttributeContainer attributeContainer, Set<Attribute> attributesToRemove) throws IllegalArgumentException, IllegalAccessException {
    Function<Attribute, Boolean> function = (attribute) -> attributesToRemove.contains(attribute);
    processAttributes(object, attributeContainer, function);
  }
  
  private void processAttributes(Object object, AttributeContainer attributeContainer, Function<Attribute, Boolean> function) throws IllegalArgumentException, IllegalAccessException {
 
    if (attributeContainer == null) {
      log.error("attribute container == null");
    } else {
      if (attributeContainer.getAttributes() == null) {
        log.error("attribute container returned null for getAttributes");
      }
    }
    
    for (Attribute attribute : attributeContainer.getAttributes()) {
      Field field = attribute.getField();
      if (function.apply(attribute)) {
        field.setAccessible(true);
        if (!field.getType().isPrimitive()) {
          field.set(object, null);
        }
      } else if (!attribute.isMultiValued() && attribute.getType() == Type.COMPLEX) {
        String name = field.getName();
        field.setAccessible(true);
        Object subObject = field.get(object);
        Attribute subAttribute = attributeContainer.getAttribute(name);
        processAttributes(subObject, subAttribute, function);
      } else if (attribute.isMultiValued() && attribute.getType() == Type.COMPLEX) {
        String name = field.getName();
        field.setAccessible(true);
        Object subObject = field.get(object);

        if (subObject == null) {
          continue;
        }
        
        if (Collection.class.isAssignableFrom(subObject.getClass())) {
          Collection<?> collection = (Collection<?>) subObject;
          for(Object o : collection) {
            Attribute subAttribute = attributeContainer.getAttribute(name);
            processAttributes(o, subAttribute, function);
          }
        } else if (field.getType().isArray()) {
          Object [] array = (Object []) subObject;
          
          for(Object o : array) {
            Attribute subAttribute = attributeContainer.getAttribute(name);
            processAttributes(o, subAttribute, function);
          }
        }
        
      }
    }
  }

  
  
  public Set<AttributeReference> getAttributeReferences(String s) {
    Set<AttributeReference> attributeReferences = new HashSet<>();

    String[] split = StringUtils.split(s, ",");

    for (String af : split) {
      AttributeReference attributeReference = new AttributeReference(af);
      attributeReferences.add(attributeReference);
    }

    return attributeReferences;
  }
  
  private Set<Attribute> resolveAttributeReferences(Set<AttributeReference> attributeReferences) throws AttributeDoesNotExistException {
    Set<Attribute> attributes = new HashSet<>();

    for (AttributeReference attributeReference : attributeReferences) {
      attributes.add(findAttribute(attributeReference));
    }

    return attributes;
  }

  private Attribute findAttribute(AttributeReference attributeReference) throws AttributeDoesNotExistException {
    String schemaUrn = attributeReference.getUrn();
    String[] attributeNames = attributeReference.getAttributeName();
    Schema schema = null;

    if (!StringUtils.isEmpty(schemaUrn)) {
      schema = registry.getSchema(schemaUrn);

      Attribute attribute = findAttributeInSchema(schema, attributeNames);
      if (attribute == null) {
        throw new AttributeDoesNotExistException(attributeReference.getFullyQualifiedAttributeName());
      }
      return attribute;
    }

    // Handle unqualified attributes, look in the core schemas
    schema = registry.getSchema(ScimUser.SCHEMA_URI);
    Attribute attribute = findAttributeInSchema(schema, attributeNames);
    if (attribute != null) {
      return attribute;
    }

    schema = registry.getSchema(ScimGroup.SCHEMA_URI);
    attribute = findAttributeInSchema(schema, attributeNames);
    if (attribute != null) {
      return attribute;
    }

    throw new AttributeDoesNotExistException(attributeReference.getFullyQualifiedAttributeName());
  }

  private Attribute findAttributeInSchema(Schema schema, String[] attributeNames) throws AttributeDoesNotExistException {
    AttributeContainer attributeContainer = schema;

    for (String attributeName : attributeNames) {
      attributeContainer = attributeContainer.getAttribute(attributeName);
      if (attributeContainer == null) {
        break;
      }
    }
    return (Attribute) attributeContainer;
  }

}
<commit_msg>Adding BVF @NotNull to an argument that can't be null<commit_after>package edu.psu.swe.scim.server.utility;

import java.lang.reflect.Field;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Function;

import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.validation.constraints.NotNull;

import org.apache.commons.lang3.StringUtils;

import edu.psu.swe.scim.server.exception.AttributeDoesNotExistException;
import edu.psu.swe.scim.server.schema.Registry;
import edu.psu.swe.scim.spec.protocol.attribute.AttributeReference;
import edu.psu.swe.scim.spec.resources.ScimGroup;
import edu.psu.swe.scim.spec.resources.ScimResource;
import edu.psu.swe.scim.spec.resources.ScimUser;
import edu.psu.swe.scim.spec.schema.AttributeContainer;
import edu.psu.swe.scim.spec.schema.Schema;
import edu.psu.swe.scim.spec.schema.Schema.Attribute;
import edu.psu.swe.scim.spec.schema.Schema.Attribute.Returned;
import edu.psu.swe.scim.spec.schema.Schema.Attribute.Type;
import lombok.extern.slf4j.Slf4j;

@Stateless
@Slf4j
public class AttributeUtil {

  @Inject
  Registry registry;

  public <T extends ScimResource> T setAttributesForDisplay(T resource) throws IllegalArgumentException, IllegalAccessException, AttributeDoesNotExistException {
    String resourceType = resource.getResourceType();
    Schema schema = registry.getBaseSchemaOfResourceType(resourceType);

    // return always and default, exclude never and requested
    removeAttributesOfType(resource, schema, Returned.REQUEST);
    removeAttributesOfType(resource, schema, Returned.NEVER);
    return resource;
  }
  
  public <T extends ScimResource> T setAttributesForDisplay(T resource, Set<AttributeReference> attributes) throws IllegalArgumentException, IllegalAccessException, AttributeDoesNotExistException {
    if (attributes.isEmpty()) {
      return setAttributesForDisplay(resource);
    } else {
      String resourceType = resource.getResourceType();
      Schema schema = registry.getBaseSchemaOfResourceType(resourceType);

      // return always and specified attributes, exclude never
      log.debug(" ### Resolve attribute reference");
      Set<Attribute> attributesToKeep = resolveAttributeReferences(attributes);
      log.debug(" ### Remove attributes of type default");
      removeAttributesOfType(resource, schema, Returned.DEFAULT, attributesToKeep);
      log.debug(" ### Remove attributes of type request");
      removeAttributesOfType(resource, schema, Returned.REQUEST, attributesToKeep);
      log.debug(" ### Remove attributes of type never");
      removeAttributesOfType(resource, schema, Returned.NEVER, attributesToKeep);
    }

    return resource;
  }

  public <T extends ScimResource> T setExcludedAttributesForDisplay(T resource, Set<AttributeReference> excludedAttributes) throws IllegalArgumentException, IllegalAccessException, AttributeDoesNotExistException {
   
    if (excludedAttributes.isEmpty()) {
      return setAttributesForDisplay(resource);
    } else {
      String resourceType = resource.getResourceType();
      Schema schema = registry.getBaseSchemaOfResourceType(resourceType);

      // return always and default, exclude never and specified attributes
      Set<Attribute> attributesToRemove = resolveAttributeReferences(excludedAttributes);
      removeAttributesOfType(resource, schema, Returned.REQUEST);
      removeAttributesOfType(resource, schema, Returned.NEVER);
      removeAttributes(resource, schema, attributesToRemove);
    }

    return resource;
  }

  private void removeAttributesOfType(Object object, AttributeContainer attributeContainer, Returned returned) throws IllegalArgumentException, IllegalAccessException {
    Function<Attribute, Boolean> function = (attribute) -> returned == attribute.getReturned();
    processAttributes(object, attributeContainer, function);
  }

  private void removeAttributesOfType(Object object, AttributeContainer attributeContainer, Returned returned, Set<Attribute> attributesToKeep) throws IllegalArgumentException, IllegalAccessException {
    Function<Attribute, Boolean> function = (attribute) -> !attributesToKeep.contains(attribute) && returned == attribute.getReturned();
    processAttributes(object, attributeContainer, function);
  }
  
  private void removeAttributes(Object object, AttributeContainer attributeContainer, Set<Attribute> attributesToRemove) throws IllegalArgumentException, IllegalAccessException {
    Function<Attribute, Boolean> function = (attribute) -> attributesToRemove.contains(attribute);
    processAttributes(object, attributeContainer, function);
  }
  
  private void processAttributes(Object object, @NotNull AttributeContainer attributeContainer, Function<Attribute, Boolean> function) throws IllegalArgumentException, IllegalAccessException {
    
    for (Attribute attribute : attributeContainer.getAttributes()) {
      Field field = attribute.getField();
      if (function.apply(attribute)) {
        field.setAccessible(true);
        if (!field.getType().isPrimitive()) {
          field.set(object, null);
        }
      } else if (!attribute.isMultiValued() && attribute.getType() == Type.COMPLEX) {
        String name = field.getName();
        field.setAccessible(true);
        Object subObject = field.get(object);
        Attribute subAttribute = attributeContainer.getAttribute(name);
        processAttributes(subObject, subAttribute, function);
      } else if (attribute.isMultiValued() && attribute.getType() == Type.COMPLEX) {
        String name = field.getName();
        field.setAccessible(true);
        Object subObject = field.get(object);

        if (subObject == null) {
          continue;
        }
        
        if (Collection.class.isAssignableFrom(subObject.getClass())) {
          Collection<?> collection = (Collection<?>) subObject;
          for(Object o : collection) {
            Attribute subAttribute = attributeContainer.getAttribute(name);
            processAttributes(o, subAttribute, function);
          }
        } else if (field.getType().isArray()) {
          Object [] array = (Object []) subObject;
          
          for(Object o : array) {
            Attribute subAttribute = attributeContainer.getAttribute(name);
            processAttributes(o, subAttribute, function);
          }
        }
        
      }
    }
  }

  
  
  public Set<AttributeReference> getAttributeReferences(String s) {
    Set<AttributeReference> attributeReferences = new HashSet<>();

    String[] split = StringUtils.split(s, ",");

    for (String af : split) {
      AttributeReference attributeReference = new AttributeReference(af);
      attributeReferences.add(attributeReference);
    }

    return attributeReferences;
  }
  
  private Set<Attribute> resolveAttributeReferences(Set<AttributeReference> attributeReferences) throws AttributeDoesNotExistException {
    Set<Attribute> attributes = new HashSet<>();

    for (AttributeReference attributeReference : attributeReferences) {
      attributes.add(findAttribute(attributeReference));
    }

    return attributes;
  }

  private Attribute findAttribute(AttributeReference attributeReference) throws AttributeDoesNotExistException {
    String schemaUrn = attributeReference.getUrn();
    String[] attributeNames = attributeReference.getAttributeName();
    Schema schema = null;

    if (!StringUtils.isEmpty(schemaUrn)) {
      schema = registry.getSchema(schemaUrn);

      Attribute attribute = findAttributeInSchema(schema, attributeNames);
      if (attribute == null) {
        throw new AttributeDoesNotExistException(attributeReference.getFullyQualifiedAttributeName());
      }
      return attribute;
    }

    // Handle unqualified attributes, look in the core schemas
    schema = registry.getSchema(ScimUser.SCHEMA_URI);
    Attribute attribute = findAttributeInSchema(schema, attributeNames);
    if (attribute != null) {
      return attribute;
    }

    schema = registry.getSchema(ScimGroup.SCHEMA_URI);
    attribute = findAttributeInSchema(schema, attributeNames);
    if (attribute != null) {
      return attribute;
    }

    throw new AttributeDoesNotExistException(attributeReference.getFullyQualifiedAttributeName());
  }

  private Attribute findAttributeInSchema(Schema schema, String[] attributeNames) throws AttributeDoesNotExistException {
    AttributeContainer attributeContainer = schema;

    for (String attributeName : attributeNames) {
      attributeContainer = attributeContainer.getAttribute(attributeName);
      if (attributeContainer == null) {
        break;
      }
    }
    return (Attribute) attributeContainer;
  }

}

{'fraction_non_alphanumeric': 0.09315882722752472, 'fraction_numerical': 0.0004572212379265017, 'mean_word_length': 4.248350329934013, 'pattern_counts': {'":': 0, '<': 47, '<?xml version=': 0, '>': 53, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4337760', 'n_tokens_mistral': 4416, 'n_tokens_neox': 4351, 'n_words': 986}