<commit_before>/*
 The MIT License

 Copyright (c) 2009-2010 <NAME>, Jr.

 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
 "Software"), to deal in the Software without restriction, including
 without limitation the rights to use, copy, modify, merge, publish,
 distribute, sublicense, and/or sell copies of the Software, and to
 permit persons to whom the Software is furnished to do so, subject to
 the following conditions:

 The above copyright notice and this permission notice shall be
 included in all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

package com.pholser.util.properties;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import com.pholser.util.properties.internal.SchemaValidator;
import com.pholser.util.properties.internal.ValidatedSchema;

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

/**
 * Creates instances of proxies that provide typed access to values in properties files via the <acronym
 * title="Proxied Interfaces Configured with Annotations">PICA</acronym> technique.</p>
 *
 * Inspired by <a href="http://lemnik.wordpress.com/2007/03/28/code-at-runtime-in-java-56/">this blog entry</a>.
 *
 * @param <T> the type of bound property accessor objects this binder creates
 * @author <a href="http://www.pholser.com"><NAME></a>
 */
public final class PropertyBinder<T> {
    private final ValidatedSchema<T> validatedSchema;

    private PropertyBinder(Class<T> schema) {
        validatedSchema = new SchemaValidator().validate(schema);
    }

    /**
     * Creates a new properties file accessor from the given PICA schema.
     *
     * The PICA schema is validated to ensure that there are no inconsistencies. Here are the constraints placed
     * on the PICA schema:
     *
     * <ol>
     * <li>Must be an interface with no superinterfaces.</li>
     *
     * <li>Every method maps to a properties file key. It can be marked with {@link BoundProperty} to indicate
     * the properties file key; if not, the key is the fully qualified name of the PICA interface + '.' + the
     * method's name.</li>
     *
     * <li>It is not required that the method accept zero arguments, but be advised that any arguments the
     * method declares are ignored.</li>
     *
     * <li>The only aggregate return types supported are arrays and {@link java.util.List}.</li>
     *
     * <li>The {@link ValuesSeparatedBy} annotation can be applied only to methods with an aggregate return
     * type, and must specify a well-formed {@linkplain java.util.regex.Pattern regular expression} as a
     * separator.</li>
     *
     * <li>A method's return type must be a <dfn>value type</dfn>, an array of value types, or a List of value
     * types. A value type is any primitive type (except {@code void}), primitive wrapper type (except
     * {@link Void}), or type which possesses either:
     *
     * <ul>
     * <li>a {@code public static} method called {@code valueOf} which takes one argument, of type
     * {@link String}, and whose return type is the type itself</li>
     *
     * <li>a {@code public} constructor which takes one argument, of type {@link String}</li>
     * </ul>
     *
     * If a value type has both of these, the {@code valueOf} method takes priority over the constructor. Note
     * that {@code enum}s have a {@code valueOf} method.</li>
     *
     * <li>A List type may be a raw List or a {@code List<?>}. The underlying values are {@code String}s in such
     * cases.</li>
     *
     * <li>If the method specifies a default value via {@link ValuesSeparatedBy}, that value must be convertible
     * to the return type of the method.</li>
     * </ol>
     *
     * @param <U> the type of bound property accessor objects this binder creates
     * @param schema the PICA type used to configure the accessor and provide access to properties
     * @return a new property binder that binds instances of {@code} schema to properties objects
     * @throws NullPointerException if {@code schema} is {@code null}
     * @throws IllegalArgumentException if {@code schema}'s configuration is invalid in any way
     */
    public static <U> PropertyBinder<U> forType(Class<U> schema) {
        return new PropertyBinder<U>(schema);
    }

    /**
     * Binds the properties purported to be in the given input stream to an instance of this binder's PICA.>
     *
     * @see #bind(File)
     * @param propertyInput an input stream containing properties to be bound
     * @return a PICA instance bound to the properties
     * @throws IOException if there is a problem reading from the input stream
     * @throws NullPointerException if {@code propertyInput} is {@code null}
     */
    public T bind(InputStream propertyInput) throws IOException {
        return bind(loadProperties(propertyInput));
    }

    /**<commit_msg>javadoc fix<commit_after>/*
 The MIT License

 Copyright (c) 2009-2010 <NAME>, Jr.

 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
 "Software"), to deal in the Software without restriction, including
 without limitation the rights to use, copy, modify, merge, publish,
 distribute, sublicense, and/or sell copies of the Software, and to
 permit persons to whom the Software is furnished to do so, subject to
 the following conditions:

 The above copyright notice and this permission notice shall be
 included in all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

package com.pholser.util.properties;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import com.pholser.util.properties.internal.SchemaValidator;
import com.pholser.util.properties.internal.ValidatedSchema;

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

/**
 * Creates instances of proxies that provide typed access to values in properties files via the <acronym
 * title="Proxied Interfaces Configured with Annotations">PICA</acronym> technique.</p>
 *
 * Inspired by <a href="http://lemnik.wordpress.com/2007/03/28/code-at-runtime-in-java-56/">this blog entry</a>.
 *
 * @param <T> the type of bound property accessor objects this binder creates
 * @author <a href="http://www.pholser.com"><NAME></a>
 */
public final class PropertyBinder<T> {
    private final ValidatedSchema<T> validatedSchema;

    private PropertyBinder(Class<T> schema) {
        validatedSchema = new SchemaValidator().validate(schema);
    }

    /**
     * Creates a new properties file accessor from the given PICA schema.
     *
     * The PICA schema is validated to ensure that there are no inconsistencies. Here are the constraints placed
     * on the PICA schema:
     *
     * <ol>
     * <li>Must be an interface with no superinterfaces.</li>
     *
     * <li>Every method maps to a properties file key. It can be marked with {@link BoundProperty} to indicate
     * the properties file key; if not, the key is the fully qualified name of the PICA interface + '.' + the
     * method's name.</li>
     *
     * <li>It is not required that the method accept zero arguments, but be advised that any arguments the
     * method declares are ignored.</li>
     *
     * <li>The only aggregate return types supported are arrays and {@link java.util.List}.</li>
     *
     * <li>The {@link ValuesSeparatedBy} annotation can be applied only to methods with an aggregate return
     * type, and must specify a well-formed {@linkplain java.util.regex.Pattern regular expression} as a
     * separator.</li>
     *
     * <li>A method's return type must be a <dfn>value type</dfn>, an array of value types, or a List of value
     * types. A value type is any primitive type (except {@code void}), primitive wrapper type (except
     * {@link Void}), or type which possesses either:
     *
     * <ul>
     * <li>a {@code public static} method called {@code valueOf} which takes one argument, of type
     * {@link String}, and whose return type is the type itself</li>
     *
     * <li>a {@code public} constructor which takes one argument, of type {@link String}</li>
     * </ul>
     *
     * If a value type has both of these, the {@code valueOf} method takes priority over the constructor. Note
     * that {@code enum}s have a {@code valueOf} method.</li>
     *
     * <li>A List type may be a raw List or a {@code List<?>}. The underlying values are {@code String}s in such
     * cases.</li>
     *
     * <li>If the method specifies a default value via {@link ValuesSeparatedBy}, that value must be convertible
     * to the return type of the method.</li>
     * </ol>
     *
     * @param <U> the type of bound property accessor objects this binder creates
     * @param schema the PICA type used to configure the accessor and provide access to properties
     * @return a new property binder that binds instances of {@code} schema to properties objects
     * @throws NullPointerException if {@code schema} is {@code null}
     * @throws IllegalArgumentException if {@code schema}'s configuration is invalid in any way
     */
    public static <U> PropertyBinder<U> forType(Class<U> schema) {
        return new PropertyBinder<U>(schema);
    }

    /**
     * Binds the properties purported to be in the given input stream to an instance of this binder's PICA.
     *
     * @see #bind(File)
     * @param propertyInput an input stream containing properties to be bound
     * @return a PICA instance bound to the properties
     * @throws IOException if there is a problem reading from the input stream
     * @throws NullPointerException if {@code propertyInput} is {@code null}
     */
    public T bind(InputStream propertyInput) throws IOException {
        return bind(loadProperties(propertyInput));
    }

    /**
{'fraction_non_alphanumeric': 0.08519437551695616, 'fraction_numerical': 0.0033085194375516956, 'mean_word_length': 3.4092382495948135, 'pattern_counts': {'":': 0, '<': 93, '<?xml version=': 0, '>': 94, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '5010823', 'n_tokens_mistral': 2953, 'n_tokens_neox': 2811, 'n_words': 1335}