/* (non-Javadoc)
@see org.jasig.services.persondir.IPersonAttributeDao#getPeopleWithMultivaluedAttributes(java.util.Map)
965786
@Override
    public final Set<IPersonAttributes> getPeopleWithMultivaluedAttributes(final Map<String, List<Object>> query,
                                                                           final IPersonAttributeDaoFilter filter) {
        Validate.notNull(query, "query may not be null.");

        //Generate the query to pass to the subclass
        final QB queryBuilder = this.generateQuery(query);
        if (queryBuilder == null && (this.queryAttributeMapping != null || this.useAllQueryAttributes == true)) {
            this.logger.debug("No queryBuilder was generated for query " + query + ", null will be returned");

            return null;
        }

        //Get the username from the query, if specified
        final IUsernameAttributeProvider usernameAttributeProvider = this.getUsernameAttributeProvider();
        final String username = usernameAttributeProvider.getUsernameFromQuery(query);

        //Execute the query in the subclass
        final List<IPersonAttributes> unmappedPeople = this.getPeopleForQuery(queryBuilder, username);
        if (unmappedPeople == null) {
            return null;
        }

        //Map the attributes of the found people according to resultAttributeMapping if it is set
        final Set<IPersonAttributes> mappedPeople = new LinkedHashSet<>();
        for (final IPersonAttributes unmappedPerson : unmappedPeople) {
            final IPersonAttributes mappedPerson = this.mapPersonAttributes(unmappedPerson);
            mappedPeople.add(mappedPerson);
        }

        return Collections.unmodifiableSet(mappedPeople);
    }
527547
public ResultList<Artwork> getPersonImages(int personId) throws MovieDbException {
        TmdbParameters parameters = new TmdbParameters();
        parameters.add(Param.ID, personId);

        URL url = new ApiUrl(apiKey, MethodBase.PERSON).subMethod(MethodSub.IMAGES).buildUrl(parameters);
        String webpage = httpTools.getRequest(url);

        try {
            WrapperImages wrapper = MAPPER.readValue(webpage, WrapperImages.class);
            ResultList<Artwork> results = new ResultList<>(wrapper.getAll(ArtworkType.PROFILE));
            wrapper.setResultProperties(results);
            return results;
        } catch (IOException ex) {
            throw new MovieDbException(ApiExceptionType.MAPPING_FAILED, "Failed to get person images", url, ex);
        }
    }
745083
@Override
    @JsonIgnore
    public Set<String> getPossibleUserAttributeNames(final IPersonAttributeDaoFilter filter) {
        return this.cachedPersonAttributesDao.getPossibleUserAttributeNames(filter);
    }
739870
@Override
    protected List<IPersonAttributes> getPeopleForQuery(final PartialWhereClause queryBuilder, final String queryUserName) {
        //Execute the query
        final RowMapper<R> rowMapper = this.getRowMapper();

        final List<R> results;
        if (queryBuilder != null) {
            //Merge the generated SQL with the base query template
            final StringBuilder partialSqlWhere = queryBuilder.sql;
            final Matcher queryMatcher = WHERE_PLACEHOLDER.matcher(this.queryTemplate);
            final String querySQL = queryMatcher.replaceAll(partialSqlWhere.toString());

            results = this.simpleJdbcTemplate.query(querySQL, rowMapper, queryBuilder.arguments.toArray());

            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Executed '" + this.queryTemplate + "' with arguments " + queryBuilder.arguments + " and got results " + results);
            }
        } else {
            results = this.simpleJdbcTemplate.query(this.queryTemplate, rowMapper);

            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Executed '" + this.queryTemplate + "' and got results " + results);
            }
        }

        return this.parseAttributeMapFromResults(results, queryUserName);
    }
290541
protected Pair<String, Map<String, List<Object>>> convertPersonAttributesToPrincipal(final String extractedPrincipalId,
                                                                                         final Map<String, List<Object>> attributes) {
        val convertedAttributes = new LinkedHashMap<String, List<Object>>();
        attributes.forEach((key, attrValue) -> {
            val values = CollectionUtils.toCollection(attrValue, ArrayList.class);
            LOGGER.debug("Found attribute [{}] with value(s) [{}]", key, values);
            if (values.size() == 1) {
                val value = CollectionUtils.firstElement(values).get();
                convertedAttributes.put(key, CollectionUtils.wrapList(value));
            } else {
                convertedAttributes.put(key, values);
            }
        });

        var principalId = extractedPrincipalId;

        if (StringUtils.isNotBlank(this.principalAttributeNames)) {
            val attrNames = org.springframework.util.StringUtils.commaDelimitedListToSet(this.principalAttributeNames);
            val result = attrNames.stream()
                .map(String::trim)
                .filter(attributes::containsKey)
                .map(attributes::get)
                .findFirst();

            if (result.isPresent()) {
                val values = result.get();
                if (!values.isEmpty()) {
                    principalId = CollectionUtils.firstElement(values).get().toString();
                    LOGGER.debug("Found principal id attribute value [{}] and removed it from the collection of attributes", principalId);
                }
            } else {
                LOGGER.warn("Principal resolution is set to resolve the authenticated principal via attribute(s) [{}], and yet "
                    + "the collection of attributes retrieved [{}] do not contain any of those attributes. This is likely due to misconfiguration "
                    + "and CAS will switch to use [{}] as the final principal id", this.principalAttributeNames, attributes.keySet(), principalId);
            }
        }

        return Pair.of(principalId, convertedAttributes);
    }
1068951
protected Map<String, List<Object>> getCasPrincipalAttributes(final Map<String, Object> model, final RegisteredService registeredService) {
        return getPrincipalAttributesAsMultiValuedAttributes(model);
    }
290176
@Override
    @JsonIgnore
    public Set<String> getAvailableQueryAttributes(final IPersonAttributeDaoFilter filter) {
        final IUsernameAttributeProvider usernameAttributeProvider = super.getUsernameAttributeProvider();
        return Collections.singleton(usernameAttributeProvider.getUsernameAttribute());
    }
909360
@JsonIgnore
    protected static IPersonAttributeDao getAttributeRepository() {
        val repositories = ApplicationContextProvider.getAttributeRepository();
        return repositories.orElse(null);
    }
637694
@Override
    protected List<IPersonAttributes> getPeopleForQuery(final String seedValue, final String queryUserName) {
        if (seedValue != null && seedValue.contains(IPersonAttributeDao.WILDCARD)) {
            final Pattern seedPattern = PatternHelper.compilePattern(seedValue);

            final List<IPersonAttributes> results = new LinkedList<>();

            for (final Map.Entry<String, Map<String, List<Object>>> attributesEntry : this.backingMap.entrySet()) {
                final String attributesKey = attributesEntry.getKey();
                final Matcher keyMatcher = seedPattern.matcher(attributesKey);
                if (keyMatcher.matches()) {
                    final Map<String, List<Object>> attributes = attributesEntry.getValue();
                    if (attributes != null) {
                        final IPersonAttributes person = this.createPerson(null, queryUserName, attributes);
                        results.add(person);
                    }
                }
            }

            if (results.size() == 0) {
                return null;
            }

            return results;
        }

        final Map<String, List<Object>> attributes = this.backingMap.get(seedValue);

        if (attributes == null) {
            return null;
        }

        final IPersonAttributes person = this.createPerson(seedValue, queryUserName, attributes);
        final List list = new ArrayList();
        list.add(person);

        return list;
    }
1236062
@Override
    public Set<IPortletEntity> getPortletEntitiesForUser(int userId) {
        final Set<IPortletEntity> portletEntities =
                this.delegatePortletEntityDao.getPortletEntitiesForUser(userId);
        return this.wrapEntities(portletEntities);
    }
59808
@Override
    public Object mapFromAttributes(final Attributes attributes) throws NamingException {
        final int attributeCount = attributes.size();
        final Map<String, Object> mapOfAttrValues = this.createAttributeMap(attributeCount);

        for (final NamingEnumeration<? extends Attribute> attributesEnum = attributes.getAll(); attributesEnum.hasMore(); ) {
            final Attribute attribute = attributesEnum.next();

            if (!this.ignoreNull || attribute.size() > 0) {
                final String attrName = attribute.getID();
                final String key = this.getAttributeKey(attrName);

                final NamingEnumeration<?> valuesEnum = attribute.getAll();
                final List<?> values = this.getAttributeValues(valuesEnum);

                mapOfAttrValues.put(key, values);
            }
        }

        return mapOfAttrValues;
    }
775657
@SuppressWarnings("unchecked")
    public static Map<String, Set<String>> getAttributes(Subject subject) {
        Map<String, Set<String>> attributes = null;

        if (subject.getPublicCredentials() == null) {
            return new HashMap<String, Set<String>>();
        }

        @SuppressWarnings("rawtypes")
        Iterator<HashMap> credentialObjects = subject.getPublicCredentials(HashMap.class).iterator();
        while (attributes == null && credentialObjects.hasNext()) {
            HashMap<?,?> credentialObject = credentialObjects.next();

            if (logger.isDebugEnabled()) {
                logger.debug("checking for attributes (class name): "
                        + credentialObject.getClass().getName());
            }

            Object key = null;
            Iterator<?> keys = null;

            keys = credentialObject.keySet().iterator();
            if (!keys.hasNext()) {
                continue;
            }

            key = keys.next();

            if (logger.isDebugEnabled()) {
                logger.debug("checking for attributes (key object name): "
                        + key.getClass().getName());
            }

            if (!(key instanceof String)) {
                continue;
            }

            keys = credentialObject.values().iterator();
            if (!keys.hasNext()) {
                continue;
            }

            key = keys.next();

            if (logger.isDebugEnabled()) {
                logger.debug("checking for attributes (value object name): "
                        + key.getClass().getName());
            }

            if (!(key instanceof HashSet)) {
                continue;
            }

            attributes = (Map<String, Set<String>>) credentialObject;
        }

        if (attributes == null) {
            attributes = new HashMap<String, Set<String>>();
            subject.getPublicCredentials().add(attributes);
        }

        return attributes;
    }
1099544
@SuppressWarnings("unchecked")
    public Multimap<String, Processor> getAllRequiredAttributes() {
        Multimap<String, Processor> requiredInputs = HashMultimap.create();
        for (ProcessorGraphNode root: this.roots) {
            final BiMap<String, String> inputMapper = root.getInputMapper();
            for (String attr: inputMapper.keySet()) {
                requiredInputs.put(attr, root.getProcessor());
            }
            final Object inputParameter = root.getProcessor().createInputParameter();
            if (inputParameter instanceof Values) {
                continue;
            } else if (inputParameter != null) {
                final Class<?> inputParameterClass = inputParameter.getClass();
                final Set<String> requiredAttributesDefinedInInputParameter =
                        getAttributeNames(inputParameterClass,
                                          FILTER_ONLY_REQUIRED_ATTRIBUTES);
                for (String attName: requiredAttributesDefinedInInputParameter) {
                    try {
                        if (inputParameterClass.getField(attName).getType() == Values.class) {
                            continue;
                        }
                    } catch (NoSuchFieldException e) {
                        throw new RuntimeException(e);
                    }
                    String mappedName = ProcessorUtils.getInputValueName(
                            root.getProcessor().getInputPrefix(),
                            inputMapper, attName);
                    requiredInputs.put(mappedName, root.getProcessor());
                }
            }
        }

        return requiredInputs;
    }
649571
protected Set<Event> resolveMultifactorProviderViaPredicate(final Optional<RequestContext> context,
                                                                final RegisteredService service,
                                                                final Principal principal,
                                                                final Collection<MultifactorAuthenticationProvider> providers) {
        val attributeNames = commaDelimitedListToSet(casProperties.getAuthn().getMfa().getGlobalPrincipalAttributeNameTriggers());
        return multifactorAuthenticationProviderResolver.resolveEventViaPrincipalAttribute(principal, attributeNames, service, context, providers,
            input -> providers.stream().anyMatch(provider -> input != null && provider.matches(input)));
    }
611827
@Override
    public final Set<IPersonAttributes> mergeResults(final Set<IPersonAttributes> toModify, final Set<IPersonAttributes> toConsider) {
        Validate.notNull(toModify, "toModify cannot be null");
        Validate.notNull(toConsider, "toConsider cannot be null");

        //Convert the toModify Set into a Map to allow for easier lookups
        final Map<String, IPersonAttributes> toModfyPeople = new LinkedHashMap<>();
        for (final IPersonAttributes toModifyPerson : toModify) {
            toModfyPeople.put(toModifyPerson.getName(), toModifyPerson);
        }

        //Merge in the toConsider people
        for (final IPersonAttributes toConsiderPerson : toConsider) {
            final String toConsiderName = toConsiderPerson.getName();
            final IPersonAttributes toModifyPerson = toModfyPeople.get(toConsiderName);

            //No matching toModify person, just add the new person
            if (toModifyPerson == null) {
                toModify.add(toConsiderPerson);
            }
            //Matching toModify person, merge their attributes
            else {
                final Map<String, List<Object>> toModifyAttributes = this.buildMutableAttributeMap(toModifyPerson.getAttributes());
                final Map<String, List<Object>> mergedAttributes = this.mergePersonAttributes(toModifyAttributes, toConsiderPerson.getAttributes());
                final NamedPersonImpl mergedPerson = new NamedPersonImpl(toConsiderName, mergedAttributes);

                //Remove then re-add the mergedPerson entry
                toModify.remove(mergedPerson);
                toModify.add(mergedPerson);
            }
        }

        return toModify;
    }
1194765
private Object[] getPersonGroupMemberKeys(IGroupMember gm) {
        Object[] keys = null;
        EntityIdentifier ei = gm.getUnderlyingEntityIdentifier();
        IPersonAttributes attr = personAttributeDao.getPerson(ei.getKey());
        if (attr != null && attr.getAttributes() != null && !attr.getAttributes().isEmpty()) {
            IPerson p = PersonFactory.createPerson();
            p.setAttributes(attr.getAttributes());
            keys = p.getAttributeValues(memberOfAttributeName);
            log.debug("Groups for person {} is: {}", p.getUserName(), Arrays.toString(keys));
        }
        return keys != null ? keys : new Object[] {};
    }
514149
@Override
    public void setAttribute(String name, List<String> values) {
        for (LocalAccountPersonAttributeImpl attribute : attributes) {
            if (name.equals(attribute.getName())) {
                attribute.setValues(values);
                return;
            }
        }

        attributes.add(new LocalAccountPersonAttributeImpl(name, values));
    }