All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.workday.autoparse.xml.context.XmlParserSettingsBuilder Maven / Gradle / Ivy

/*
 * Copyright 2015 Workday, Inc.
 *
 * This software is available under the MIT license.
 * Please see the LICENSE.txt file in this project.
 */

package com.workday.autoparse.xml.context;

import com.workday.autoparse.xml.annotations.XmlParserPartition;
import com.workday.autoparse.xml.parser.GeneratedClassNames;
import com.workday.autoparse.xml.parser.ParserMap;
import com.workday.autoparse.xml.parser.XmlElementParser;
import com.workday.autoparse.xml.parser.XmlStreamParser;
import com.workday.autoparse.xml.utils.StringTransformer;
import com.workday.meta.ConcreteTypeNames;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

/**
 * @author nathan.taylor
 * @since 2013-9-23-11:52
 */
public class XmlParserSettingsBuilder {

    public static final String DEFAULT_PACKAGE = ParserMap.class.getPackage().getName();

    private Class unknownElementClass;
    private XmlElementParser unknownElementParser;
    private XmlParserSettings.UnknownElementHandling unknownElementHandling =
            XmlParserSettings.UnknownElementHandling.PARSE;
    private boolean ignoreUnexpectedChildren;
    private List partitionPackages = new ArrayList<>();
    private List stringFilters = new ArrayList<>();

    /**
     * Use the given {@link XmlParserSettings.UnknownElementHandling} when parsing. This value
     * defaults to {@link XmlParserSettings.UnknownElementHandling#PARSE}.
     *
     * @param unknownElementHandling The unknown element handling strategy to use.
     *
     * @return This SettingsBuilder.
     */
    public XmlParserSettingsBuilder withUnknownElementHandling(XmlParserSettings
                                                                       .UnknownElementHandling
                                                                       unknownElementHandling) {
        this.unknownElementHandling = unknownElementHandling;
        return this;
    }

    /**
     * If {@code ignoreUnexpectedChildren} is {@code true}, then when the autoparse encounters a
     * child element for which there is no field in the parent class annotated with {@link
     * com.workday.autoparse.xml.annotations.XmlChildElement}, the element will be skipped.
     * 

* If {@code ignoreUnexpectedChildren} is {@code false}, then when the autoparse encounters a * child element for which there is no field in the parent class annotated with {@link * com.workday.autoparse.xml.annotations.XmlChildElement}, then an {@link * com.workday.autoparse.xml.parser.UnexpectedChildException} will be thrown. * * @param ignoreUnexpectedChildren {@code true} if undeclared children will be ignored, {@code * false} if an exception should be thrown when an undeclared child is encountered. * * @return This SettingsBuilder. */ public XmlParserSettingsBuilder ignoreUnexpectedChildren(boolean ignoreUnexpectedChildren) { this.ignoreUnexpectedChildren = ignoreUnexpectedChildren; return this; } public XmlParserSettingsBuilder withUnknownElementParser(XmlElementParser unknownElementParser, Class unknownElementType) { this.unknownElementParser = unknownElementParser; this.unknownElementClass = unknownElementType; return this; } /** * You can use this method to set the unknown element parser if that parser was generated by * Autoparse. * * @param unknownObjectClass The type of object that will be created when an unknown element tag * is encountered in the XML document. This class must be annotated with {@literal@}{@link * com.workday.autoparse.xml.annotations.XmlUnknownElement}. */ public XmlParserSettingsBuilder withUnknownElementClass(Class unknownObjectClass) { this.unknownElementClass = unknownObjectClass; String parserName = ConcreteTypeNames.constructClassName(unknownObjectClass, GeneratedClassNames.PARSER_SUFFIX); try { @SuppressWarnings("unchecked") Class> parserClass = (Class>) Class.forName( parserName); Object instance = parserClass.getDeclaredField("INSTANCE").get(null); if (!(instance instanceof XmlElementParser)) { throw new RuntimeException( "Public constant INSTANCE must be of type XmlElementParser"); } unknownElementParser = (XmlElementParser) instance; } catch (ClassNotFoundException e) { throw new RuntimeException("No XmlElementParser found for class of type " + unknownObjectClass, e); } catch (NoSuchFieldException e) { throw new RuntimeException("Parser does not have static field named INSTANCE.", e); } catch (IllegalAccessException e) { throw new RuntimeException("Field INSTANCE is not public.", e); } catch (NullPointerException e) { throw new RuntimeException("Field INSTANCE is not static", e); } return this; } /** * Indicate which partitions the {@link XmlStreamParser} should use. If no partitions are * indicated, the default partition is assumed. To include explicit partitions and the default * partition, include {@link #DEFAULT_PACKAGE} in the list. *

* When the {@link XmlParserSettings} instance is created, a validation is performed to ensure * that there are no name collisions (multiple classes mapping to the same XML element tag) * among the partitions. If there are, an {@link IllegalArgumentException} is thrown. * * @param partitionPackages The fully qualified names of the packages that hold the partitions. * These are packages annotated with {@literal@}{@link XmlParserPartition}. * * @return This SettingsBuilder. */ public XmlParserSettingsBuilder withPartitions(String... partitionPackages) { this.partitionPackages.addAll(Arrays.asList(partitionPackages)); return this; } /** * Add a new collection of filters that will be applied when parsing string attributes and text * content of elements. Filters are applied in the order they are added to all elements parsed. * * @param stringFilters The filters to be applied to all string attributes and text content. * * @return This SettingsBuilder. * * @see #addFilter(StringTransformer) */ public XmlParserSettingsBuilder addFilters(Collection stringFilters) { this.stringFilters.addAll(stringFilters); return this; } /** * Add a new filter that will be applied when parsing string attributes and text content of * elements. Filters are applied in the order they are added to all elements parsed. *

* For example, if you want replace the character "&#xa;" with "\n" you can create a {@link * StringTransformer} to do that and add it here. *

     *      StringTransformer newLineFilter = new StringTransformer() {
     *          {@literal@}Override
     *          public String apply(String input) {
     *              return input.replace('&#xa;', '\n');
     *      };
     * 
* * @param stringFilter The filter to be applied to all string attributes and text content. * * @return This SettingsBuilder. */ public XmlParserSettingsBuilder addFilter(StringTransformer stringFilter) { stringFilters.add(stringFilter); return this; } /** * Creates a new instance of {@link XmlParserSettings} with the specified preferences set. * * @return The new Settings instance. */ public XmlParserSettings build() { if (partitionPackages.isEmpty()) { partitionPackages.add(DEFAULT_PACKAGE); } return new XmlParserSettings(unknownElementHandling, ignoreUnexpectedChildren, unknownElementClass, unknownElementParser, stringFilters, partitionPackages); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy