<commit_before>package org.kuali.rice.core.cxf.interceptors;

import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * A CXF Interceptor that binds itself to the USER_LOGICAL phase to be used on inbound
 * messages.  This interceptor is invoked in the interceptor chain after unmarshalling
 * from XML to Java has occurred.  The role of this interceptor is to ensure that any
 * Collection (and specifically List, Set, or Map) used in a @WebMethod is ultimately of the
 * type returned from
 */
@SuppressWarnings("unused")
public class ImmutableCollectionsInInterceptor extends AbstractPhaseInterceptor<Message> {

    /**
     * Instantiates an ImmutableCollectionsInInterceptor
     */
    public ImmutableCollectionsInInterceptor() {
        super(Phase.USER_LOGICAL);
    }

    @Override
    @SuppressWarnings("unchecked")
    public void handleMessage(final Message message) throws Fault {
        List contents = message.getContent(List.class);
        for (int i = 0; i < contents.size(); i++) {
            Object o = contents.get(i);
            if (o instanceof List) {
                List unmodifiable = Collections.unmodifiableList((List) o);
                contents.set(i, unmodifiable);
            }
            else if (o instanceof Set) {
                Set unmodifiable = Collections.unmodifiableSet((Set) o);
                contents.set(i, unmodifiable);
            }
            else if (o instanceof Collection) {
                Collection unmodifiable = Collections.unmodifiableCollection((Collection) o);
                contents.set(i,unmodifiable);
            } else if (o instanceof Map) {
                Map unmodifiable = Collections.unmodifiableMap((Map) o);
                contents.set(i, unmodifiable);
            }
        }
    }
}<commit_msg>KULRICE-5340:  changed reflection techniques on ImmutableCollectionsInInterceptor to truly modify fields of the response wrapper class that are List, Set or Collection classes<commit_after>package org.kuali.rice.core.cxf.interceptors;

import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;

import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * A CXF Interceptor that binds itself to the USER_LOGICAL phase to be used on inbound
 * messages.  This interceptor is invoked in the interceptor chain after unmarshalling
 * from XML to Java has occurred.  The role of this interceptor is to ensure that any
 * Collection (and specifically List, Set, or Map) used in a @WebMethod is ultimately of the
 * expected immutable type returned from the local service.
 */
@SuppressWarnings("unused")
public class ImmutableCollectionsInInterceptor extends AbstractPhaseInterceptor<Message> {

    /**
     * Instantiates an ImmutableCollectionsInInterceptor and adds it to the USER_LOGICAL phase.
     */
    public ImmutableCollectionsInInterceptor() {
        super(Phase.USER_LOGICAL);
    }

    @Override
    public void handleMessage(final Message message) throws Fault {
        try {
            List contents = message.getContent(List.class);
            for (Object o : contents) {
                makeCollectionFieldsImmutable(o);
            }
        } catch (Exception e) {
            throw new Fault(e);
        }
    }

    /**
     * Accepts an object whose fields of type List, Set, or Collection need to be made immutable irrespective of field
     * visibility.  The passed in object is mutated as a result.
     *
     * @param o - The object whose List, Set, or Collection fields will be made immutable
     * @throws IllegalAccessException
     */
    @SuppressWarnings("unchecked")
    void makeCollectionFieldsImmutable(Object o) throws IllegalAccessException {
        Class<?> targetClass = o.getClass();
        for (Field f : targetClass.getDeclaredFields()) {

            f.setAccessible(true);

            if (f.getType().isAssignableFrom(List.class)) {
                List original = (List) f.get(o);
                if (original == null) {
                    original = Collections.emptyList();
                }
                List immutable = Collections.unmodifiableList(original);
                f.set(o, immutable);

            } else if (f.getType().isAssignableFrom(Set.class)) {
                Set original = (Set) f.get(o);
                if (original == null) {
                    original = Collections.emptySet();
                }
                Set immutable = Collections.unmodifiableSet(original);
                f.set(o, immutable);
            } else if (f.getType().isAssignableFrom(Collection.class)) {
                Collection original = (Collection) f.get(o);
                if (original == null) {
                    original = Collections.emptyList();
                }
                Collection immutable = Collections.unmodifiableCollection(original);
                f.set(o, immutable);
            }

            f.setAccessible(false);
        }
    }
}
{'fraction_non_alphanumeric': 0.08771603791116893, 'fraction_numerical': 0.000929195316855603, 'mean_word_length': 2.50390625, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 6, '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': '4906844', 'n_tokens_mistral': 1433, 'n_tokens_neox': 1394, 'n_words': 416}