<commit_before>package com.github.smat.saxxp;

import com.github.smat.saxxp.annotation.ParseFromXmlEnumIdentifier;
import com.github.smat.saxxp.annotation.ParseFromXmlWithXPath;
import com.github.smat.saxxp.exception.SAXXParserException;
import org.apache.commons.lang.StringUtils;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.xpath.XPath;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import static org.apache.commons.io.IOUtils.toInputStream;

public class SAXXParserFactory {
    private PrimitiveFieldParserFactory primitiveFieldParserFactory;

    public SAXXParserFactory() {
        primitiveFieldParserFactory = new PrimitiveFieldParserFactory();
    }

    public <T extends Object> SAXXParser<T> createXmlParser(Class<T> clazz) {
        if (clazz == null) {
            throw new IllegalArgumentException("Could not create parser for null class");
        }
        final List<FieldParser> parseableElements = new ArrayList<FieldParser>();

        for (Field iteratorField : clazz.getDeclaredFields()) {
            if (iteratorField.isAnnotationPresent(ParseFromXmlWithXPath.class)) {
                try {
                    final Field field = iteratorField;
                    final ParseFromXmlWithXPath annotation = field.getAnnotation(ParseFromXmlWithXPath.class);
                    final XPath xPath = XPath.newInstance(annotation.value());
                    field.setAccessible(true);

                    FieldParser fieldParser = primitiveFieldParserFactory.createFieldParser(field, xPath);
                    if (fieldParser != null) {
                        parseableElements.add(fieldParser);
                    }
                    else if (field.getType().isEnum()) {
                        Field identifierField = null;
                        for (Field enumField : field.getType().getDeclaredFields()) {
                            enumField.setAccessible(true);
                            if (enumField.isAnnotationPresent(ParseFromXmlEnumIdentifier.class)) {
                                identifierField = enumField;
                            }
                        }
                        if (identifierField == null) {
                            throw new IllegalArgumentException("Enum does not contains @ParseFromXmlEnumIdentifier annotation");
                        }
                        final Field enumIdentifier = identifierField;
                        parseableElements.add(new EnumFieldParser(field, xPath, enumIdentifier));
                    }
                    else if (List.class.isAssignableFrom(field.getType())) {
                        Type genericType = field.getGenericType();
                        if (genericType instanceof ParameterizedType) {
                            ParameterizedType type = (ParameterizedType) genericType;
                            Type[] generics = type.getActualTypeArguments();
                            if (generics.length >= 1) {
                                Class elementClazz = (Class) generics[0];
                                parseableElements.add(new ListFieldParser(field, xPath, elementClazz));
                            }
                        }
                        else {
                            throw new IllegalArgumentException("List does not have a defined generic type");
                        }
                    }
                } catch (JDOMException e) {
                    throw new IllegalArgumentException("Error createing XPath, invalid expression", e);
                }
            }
        }

        return new SAXXParserImpl<T>(clazz, parseableElements);
    }

    private abstract class FieldParser<T extends Object> {
        protected final Field field;
        protected final XPath xPath;

        public abstract void parseElement(T obj, Object context) throws JDOMException, IllegalAccessException, SAXXParserException;

        public FieldParser(Field field, XPath xPath) {
            this.field = field;
            this.xPath = xPath;
        }
    }

    private class EnumFieldParser extends FieldParser {
        private final Field enumIdentifier;

        public EnumFieldParser(Field field, XPath xPath, Field enumIdentifier) {
            super(field, xPath);
            this.enumIdentifier = enumIdentifier;
        }

        @Override
        public void parseElement(Object obj, Object doc) throws JDOMException, IllegalAccessException {
            Element element = (Element) xPath.selectSingleNode(doc);
            if (element != null) {
                for (Object enumElemnt : field.getType().getEnumConstants()) {
                    if (enumIdentifier.get(enumElemnt).equals(element.getText())) {
                        field.set(obj, enumElemnt);
                        break;
                    }
                }
            }
        }
    }

    private class ListFieldParser extends FieldParser {
        private final Class elementClazz;
        private SAXXParser SAXXParser;
        private FieldParser fieldParser;

        private class ObjectWrapper {
            public Object object;
        }

        public ListFieldParser(Field field, XPath xPath, Class elementClazz) {
            super(field, xPath);
            this.elementClazz = elementClazz;
            try {
                fieldParser = primitiveFieldParserFactory.createFieldParser(ObjectWrapper.class.getField("object"), XPath.newInstance("."), elementClazz);
            } catch (NoSuchFieldException e) {
                throw new SAXXParserException("Could not create List parser", e);
            } catch (JDOMException e) {
                throw new SAXXParserException("Could not create new XPath for List parser", e);
            }
            if (fieldParser == null) {
                SAXXParser = SAXXParserFactory.this.createXmlParser(elementClazz);
            }
        }

        @Override
        public void parseElement(Object obj, Object doc) throws JDOMException, IllegalAccessException, SAXXParserException {
            ObjectWrapper wrapper = new ObjectWrapper();
            List objList = (List) field.get(obj);
            if (objList == null) {
                objList = new ArrayList();
                field.set(obj, objList);
            }
            List<Element> list = xPath.selectNodes(doc);
            for (Element element : list) {
                if (fieldParser != null) {
                    fieldParser.parseElement(wrapper, element);
                    objList.add(wrapper.object);
                } else if (SAXXParser != null) {
                    Object returnObj = SAXXParser.parse(element);
                    objList.add(returnObj);
                }
            }
        }
    }

    private class PrimitiveFieldParserFactory {
        private HashMap<Class, Class<FieldParser>> parserMap;

        PrimitiveFieldParserFactory() {
            parserMap = new HashMap<Class, Class<FieldParser>>();
            for (Class clazz : this.getClass().getDeclaredClasses()) {
                if (FieldParser.class.isAssignableFrom(clazz)) {
                    Type type = clazz.getGenericSuperclass();
                    if (type instanceof ParameterizedType) {<commit_msg>Renamed local variable<commit_after>package com.github.smat.saxxp;

import com.github.smat.saxxp.annotation.ParseFromXmlEnumIdentifier;
import com.github.smat.saxxp.annotation.ParseFromXmlWithXPath;
import com.github.smat.saxxp.exception.SAXXParserException;
import org.apache.commons.lang.StringUtils;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.xpath.XPath;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import static org.apache.commons.io.IOUtils.toInputStream;

public class SAXXParserFactory {
    private PrimitiveFieldParserFactory primitiveFieldParserFactory;

    public SAXXParserFactory() {
        primitiveFieldParserFactory = new PrimitiveFieldParserFactory();
    }

    public <T extends Object> SAXXParser<T> createXmlParser(Class<T> clazz) {
        if (clazz == null) {
            throw new IllegalArgumentException("Could not create parser for null class");
        }
        final List<FieldParser> parseableElements = new ArrayList<FieldParser>();

        for (Field iteratorField : clazz.getDeclaredFields()) {
            if (iteratorField.isAnnotationPresent(ParseFromXmlWithXPath.class)) {
                try {
                    final Field field = iteratorField;
                    final ParseFromXmlWithXPath annotation = field.getAnnotation(ParseFromXmlWithXPath.class);
                    final XPath xPath = XPath.newInstance(annotation.value());
                    field.setAccessible(true);

                    FieldParser fieldParser = primitiveFieldParserFactory.createFieldParser(field, xPath);
                    if (fieldParser != null) {
                        parseableElements.add(fieldParser);
                    }
                    else if (field.getType().isEnum()) {
                        Field identifierField = null;
                        for (Field enumField : field.getType().getDeclaredFields()) {
                            enumField.setAccessible(true);
                            if (enumField.isAnnotationPresent(ParseFromXmlEnumIdentifier.class)) {
                                identifierField = enumField;
                            }
                        }
                        if (identifierField == null) {
                            throw new IllegalArgumentException("Enum does not contains @ParseFromXmlEnumIdentifier annotation");
                        }
                        final Field enumIdentifier = identifierField;
                        parseableElements.add(new EnumFieldParser(field, xPath, enumIdentifier));
                    }
                    else if (List.class.isAssignableFrom(field.getType())) {
                        Type genericType = field.getGenericType();
                        if (genericType instanceof ParameterizedType) {
                            ParameterizedType type = (ParameterizedType) genericType;
                            Type[] generics = type.getActualTypeArguments();
                            if (generics.length >= 1) {
                                Class elementClazz = (Class) generics[0];
                                parseableElements.add(new ListFieldParser(field, xPath, elementClazz));
                            }
                        }
                        else {
                            throw new IllegalArgumentException("List does not have a defined generic type");
                        }
                    }
                } catch (JDOMException e) {
                    throw new IllegalArgumentException("Error createing XPath, invalid expression", e);
                }
            }
        }

        return new SAXXParserImpl<T>(clazz, parseableElements);
    }

    private abstract class FieldParser<T extends Object> {
        protected final Field field;
        protected final XPath xPath;

        public abstract void parseElement(T obj, Object context) throws JDOMException, IllegalAccessException, SAXXParserException;

        public FieldParser(Field field, XPath xPath) {
            this.field = field;
            this.xPath = xPath;
        }
    }

    private class EnumFieldParser extends FieldParser {
        private final Field enumIdentifier;

        public EnumFieldParser(Field field, XPath xPath, Field enumIdentifier) {
            super(field, xPath);
            this.enumIdentifier = enumIdentifier;
        }

        @Override
        public void parseElement(Object obj, Object doc) throws JDOMException, IllegalAccessException {
            Element element = (Element) xPath.selectSingleNode(doc);
            if (element != null) {
                for (Object enumElemnt : field.getType().getEnumConstants()) {
                    if (enumIdentifier.get(enumElemnt).equals(element.getText())) {
                        field.set(obj, enumElemnt);
                        break;
                    }
                }
            }
        }
    }

    private class ListFieldParser extends FieldParser {
        private final Class elementClazz;
        private SAXXParser parser;
        private FieldParser fieldParser;

        private class ObjectWrapper {
            public Object object;
        }

        public ListFieldParser(Field field, XPath xPath, Class elementClazz) {
            super(field, xPath);
            this.elementClazz = elementClazz;
            try {
                fieldParser = primitiveFieldParserFactory.createFieldParser(ObjectWrapper.class.getField("object"), XPath.newInstance("."), elementClazz);
            } catch (NoSuchFieldException e) {
                throw new SAXXParserException("Could not create List parser", e);
            } catch (JDOMException e) {
                throw new SAXXParserException("Could not create new XPath for List parser", e);
            }
            if (fieldParser == null) {
                parser = SAXXParserFactory.this.createXmlParser(elementClazz);
            }
        }

        @Override
        public void parseElement(Object obj, Object doc) throws JDOMException, IllegalAccessException, SAXXParserException {
            ObjectWrapper wrapper = new ObjectWrapper();
            List objList = (List) field.get(obj);
            if (objList == null) {
                objList = new ArrayList();
                field.set(obj, objList);
            }
            List<Element> list = xPath.selectNodes(doc);
            for (Element element : list) {
                if (fieldParser != null) {
                    fieldParser.parseElement(wrapper, element);
                    objList.add(wrapper.object);
                } else if (parser != null) {
                    Object returnObj = parser.parse(element);
                    objList.add(returnObj);
                }
            }
        }
    }

    private class PrimitiveFieldParserFactory {
        private HashMap<Class, Class<FieldParser>> parserMap;

        PrimitiveFieldParserFactory() {
            parserMap = new HashMap<Class, Class<FieldParser>>();
            for (Class clazz : this.getClass().getDeclaredClasses()) {
                if (FieldParser.class.isAssignableFrom(clazz)) {
                    Type type = clazz.getGenericSuperclass();
                    if (type instanceof ParameterizedType) {
{'fraction_non_alphanumeric': 0.07888881397073697, 'fraction_numerical': 0.0002697053469085025, 'mean_word_length': 1.8235294117647058, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 29, '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': '1887322', 'n_tokens_mistral': 3511, 'n_tokens_neox': 3381, 'n_words': 814}