<commit_before>/*
 * Copyright 2009-2014 <NAME>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 *
 * You may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *           http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.atatec.trugger.util.mock;

import org.atatec.trugger.interception.Interception;

import java.lang.annotation.Annotation;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.Predicate;

import static org.atatec.trugger.reflection.Reflection.reflect;
import static org.atatec.trugger.reflection.ReflectionPredicates.named;
import static org.atatec.trugger.reflection.MethodPredicates.withoutParameters;

/**
 * A builder for creating mock {@link Annotation annotations}.
 * <p>
 * This mock provides some useful features because annotations may have default values.
 * This class can resolve them and automatically configure the values in the mock object.
 * <p>
 * Here is an example of use:
 * <p>
 * <pre>
 * import static org.atatec.trugger.util.mock.Mock.annotation;
 * import static org.atatec.trugger.util.mock.Mock.mock;
 * import javax.annotation.Resource;
 * // ...
 * Resource resource = new AnnotationMock&lt;Resource&gt;(){{
 *       map(&quot;name&quot;).to(annotation.name());
 *       map(false).to(annotation.shareable());
 *     }}.mock();
 * String name = resource.name(); //returns &quot;name&quot;
 * boolean shareable = resource.shareable(); //return false
 * String mappedName = resource.mappedName(); //returns &quot;&quot; because it is the
 * default value
 * Class&lt;? extends Annotation&gt; type = resource.annotationType(); //return
 * javax.annotation.Resource class
 * </pre>
 * <p>
 * There are another ways to mock annotations:
 * <p>
 * <pre>
 * // if you don't need to specify any property
 * Resource resource2 = mock(annotation(Resource.class));
 *
 * // if the anonymous class looks bad to you
 * AnnotationMock&lt;Resource&gt; builder = annotation(Resource.class);
 * Resource resource3 = builder.annotation();
 * builder.map(&quot;name&quot;).to(resource3.name());
 * builder.map(false).to(resource3.shareable());
 * builder.mock(); //don't forget to call mock() to activate the mock object
 * </pre>
 *
 * @param <T> The annotation type.
 * @author <NAME>
 * @since 2.1
 */
public class AnnotationMock<T extends Annotation> implements MockBuilder<T> {

  private static final Map<Class<?>, Object> nullValues;

  static {
    nullValues = new HashMap<Class<?>, Object>() {{
      put(byte.class, (byte) 0);
      put(short.class, (short) 0);
      put(int.class, 0);
      put(long.class, 0L);
      put(char.class, (char) 0);
      put(float.class, 0f);
      put(double.class, 0d);
      put(boolean.class, false);
    }};

  }

  private final Class<T> annotationType;
  /**
   * The annotation for specifying the mappings.
   */
  protected T annotation;
  private Map<String, Object> mappings;
  private boolean mocked;
  private String lastCall;

  /**
   * @param annotationType the annotation type
   */
  public AnnotationMock(Class<T> annotationType) {
    this.annotationType = annotationType;
    initialize();
  }

  /**
   * Uses the generic parameter for defining the annotation type. So, be sure to specify
   * it.
   */
  protected AnnotationMock() {
    this.annotationType = reflect().genericType("T").in(this);
    initialize();
  }

  private void initialize() {
    this.annotation = Interception.intercept(annotationType)
        .onCall(context -> {
          Method method = context.method();
          String name = method.getName();
          if (!mocked) {
            lastCall = name;
            return nullValues.get(method.getReturnType());
          }
          return mappings.get(name);
        })
        .proxy();
    this.mappings = new HashMap<>(15);
    this.mappings.put("annotationType", annotationType);
  }

  /**
   * @return the annotation for specifying the mappings. After calling {@link
   * #createMock()} it can be used as the mocked annotation.
   */
  public T annotation() {
    return annotation;
  }

  /**
   * Maps the given value to an annotation property.
   *
   * @param <E>   The value type
   * @param value the value
   * @return the component for selecting the property.
   */
  public <E> Mapper<E, T> map(final E value) {
    return new Mapper<E, T>() {

      public org.atatec.trugger.util.mock.AnnotationMock<T> to(E expected) {
        mappings.put(lastCall, value);
        return org.atatec.trugger.util.mock.AnnotationMock.this;
      }
    };
  }

  @Override
  public T createMock() {
    Predicate<Member> predicate = null;
    for (String name : mappings.keySet()) {
      predicate = (predicate == null ? named(name) : predicate.or(named(name)));
    }
    Predicate<Member> unused = predicate.negate();
    Set<Method> methods = reflect()
        .methods()
        .filter(withoutParameters().and(unused))
        .in(annotationType);
    for (Method method : methods) {
      Object defaultValue = method.getDefaultValue();
      if (defaultValue == null) {
        throw new IllegalStateException("Property " + method.getName() + " not defined.");
      }
      mappings.put(method.getName(), defaultValue);
    }
    mocked = true;
    lastCall = null;
    return annotation;
  }

  /**
   * Interface for defining the annotation property .
   *
   * @param <E> The value type.
   * @param <T> The annotation type.
   * @author <NAME>
   * @since 2.1
   */
  public static interface Mapper<E, T extends Annotation> {

    /**
     * Selects the property to map the previous defined value.
     *
     * @return a reference to the builder.
     */
    org.atatec.trugger.util.mock.AnnotationMock<T> to(E value);
  }

}<commit_msg>no need to use full qualified name here<commit_after>/*
 * Copyright 2009-2014 <NAME>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 *
 * You may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *           http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.atatec.trugger.util.mock;

import org.atatec.trugger.interception.Interception;

import java.lang.annotation.Annotation;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.Predicate;

import static org.atatec.trugger.reflection.Reflection.reflect;
import static org.atatec.trugger.reflection.ReflectionPredicates.named;
import static org.atatec.trugger.reflection.MethodPredicates.withoutParameters;

/**
 * A builder for creating mock {@link Annotation annotations}.
 * <p>
 * This mock provides some useful features because annotations may have default values.
 * This class can resolve them and automatically configure the values in the mock object.
 * <p>
 * Here is an example of use:
 * <p>
 * <pre>
 * import static org.atatec.trugger.util.mock.Mock.annotation;
 * import static org.atatec.trugger.util.mock.Mock.mock;
 * import javax.annotation.Resource;
 * // ...
 * Resource resource = new AnnotationMock&lt;Resource&gt;(){{
 *       map(&quot;name&quot;).to(annotation.name());
 *       map(false).to(annotation.shareable());
 *     }}.mock();
 * String name = resource.name(); //returns &quot;name&quot;
 * boolean shareable = resource.shareable(); //return false
 * String mappedName = resource.mappedName(); //returns &quot;&quot; because it is the
 * default value
 * Class&lt;? extends Annotation&gt; type = resource.annotationType(); //return
 * javax.annotation.Resource class
 * </pre>
 * <p>
 * There are another ways to mock annotations:
 * <p>
 * <pre>
 * // if you don't need to specify any property
 * Resource resource2 = mock(annotation(Resource.class));
 *
 * // if the anonymous class looks bad to you
 * AnnotationMock&lt;Resource&gt; builder = annotation(Resource.class);
 * Resource resource3 = builder.annotation();
 * builder.map(&quot;name&quot;).to(resource3.name());
 * builder.map(false).to(resource3.shareable());
 * builder.mock(); //don't forget to call mock() to activate the mock object
 * </pre>
 *
 * @param <T> The annotation type.
 * @author <NAME>
 * @since 2.1
 */
public class AnnotationMock<T extends Annotation> implements MockBuilder<T> {

  private static final Map<Class<?>, Object> nullValues;

  static {
    nullValues = new HashMap<Class<?>, Object>() {{
      put(byte.class, (byte) 0);
      put(short.class, (short) 0);
      put(int.class, 0);
      put(long.class, 0L);
      put(char.class, (char) 0);
      put(float.class, 0f);
      put(double.class, 0d);
      put(boolean.class, false);
    }};

  }

  private final Class<T> annotationType;
  /**
   * The annotation for specifying the mappings.
   */
  protected T annotation;
  private Map<String, Object> mappings;
  private boolean mocked;
  private String lastCall;

  /**
   * @param annotationType the annotation type
   */
  public AnnotationMock(Class<T> annotationType) {
    this.annotationType = annotationType;
    initialize();
  }

  /**
   * Uses the generic parameter for defining the annotation type. So, be sure to specify
   * it.
   */
  protected AnnotationMock() {
    this.annotationType = reflect().genericType("T").in(this);
    initialize();
  }

  private void initialize() {
    this.annotation = Interception.intercept(annotationType)
        .onCall(context -> {
          Method method = context.method();
          String name = method.getName();
          if (!mocked) {
            lastCall = name;
            return nullValues.get(method.getReturnType());
          }
          return mappings.get(name);
        })
        .proxy();
    this.mappings = new HashMap<>(15);
    this.mappings.put("annotationType", annotationType);
  }

  /**
   * @return the annotation for specifying the mappings. After calling {@link
   * #createMock()} it can be used as the mocked annotation.
   */
  public T annotation() {
    return annotation;
  }

  /**
   * Maps the given value to an annotation property.
   *
   * @param <E>   The value type
   * @param value the value
   * @return the component for selecting the property.
   */
  public <E> Mapper<E, T> map(final E value) {
    return new Mapper<E, T>() {

      public org.atatec.trugger.util.mock.AnnotationMock<T> to(E expected) {
        mappings.put(lastCall, value);
        return org.atatec.trugger.util.mock.AnnotationMock.this;
      }
    };
  }

  @Override
  public T createMock() {
    Predicate<Member> predicate = null;
    for (String name : mappings.keySet()) {
      predicate = (predicate == null ? named(name) : predicate.or(named(name)));
    }
    Predicate<Member> unused = predicate.negate();
    Set<Method> methods = reflect()
        .methods()
        .filter(withoutParameters().and(unused))
        .in(annotationType);
    for (Method method : methods) {
      Object defaultValue = method.getDefaultValue();
      if (defaultValue == null) {
        throw new IllegalStateException("Property " + method.getName() + " not defined.");
      }
      mappings.put(method.getName(), defaultValue);
    }
    mocked = true;
    lastCall = null;
    return annotation;
  }

  /**
   * Interface for defining the annotation property .
   *
   * @param <E> The value type.
   * @param <T> The annotation type.
   * @author <NAME>
   * @since 2.1
   */
  public static interface Mapper<E, T extends Annotation> {

    /**
     * Selects the property to map the previous defined value.
     *
     * @return a reference to the builder.
     */
    AnnotationMock<T> to(E value);
  }

}
{'fraction_non_alphanumeric': 0.12535313584631527, 'fraction_numerical': 0.004681572362579708, 'mean_word_length': 3.181572730340871, 'pattern_counts': {'":': 0, '<': 73, '<?xml version=': 0, '>': 75, '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': '2651957', 'n_tokens_mistral': 3715, 'n_tokens_neox': 3586, 'n_words': 1075}