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

ch.powerunit.extensions.matchers.provideprocessor.RoundMirror Maven / Gradle / Ivy

Go to download

This is a test framework for the JDK 1.8 - Extension to provide matchers based on annotation. - Factory Support

There is a newer version: 0.1.6
Show newest version
/**
 * Powerunit - A JDK1.8 test framework
 * Copyright (C) 2014 Mathieu Boretti.
 *
 * This file is part of Powerunit
 *
 * Powerunit is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Powerunit is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Powerunit. If not, see .
 */
package ch.powerunit.extensions.matchers.provideprocessor;

import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.toList;

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Supplier;

import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
import javax.lang.model.type.TypeMirror;
import javax.tools.Diagnostic.Kind;

import ch.powerunit.extensions.matchers.AddToMatcher;
import ch.powerunit.extensions.matchers.AddToMatchers;
import ch.powerunit.extensions.matchers.IgnoreInMatcher;
import ch.powerunit.extensions.matchers.ProvideMatchers;
import ch.powerunit.extensions.matchers.common.AbstractRoundMirrorReferenceToProcessingEnv;
import ch.powerunit.extensions.matchers.provideprocessor.extension.AutomatedExtension;
import ch.powerunit.extensions.matchers.provideprocessor.extension.beanmatchers.DefaultBeanMatchersAutomatedExtension;
import ch.powerunit.extensions.matchers.provideprocessor.extension.hamcrestdate.LocalDateMatchersAutomatedExtension;
import ch.powerunit.extensions.matchers.provideprocessor.extension.hamcrestdate.LocalDateTimeMatchersAutomatedExtension;
import ch.powerunit.extensions.matchers.provideprocessor.extension.hamcrestdate.LocalTimeMatchersAutomatedExtension;
import ch.powerunit.extensions.matchers.provideprocessor.extension.hamcrestdate.ZonedDateTimeMatchersAutomatedExtension;
import ch.powerunit.extensions.matchers.provideprocessor.extension.hamcrestutility.CollectionHamcrestUtilityAutomatedExtension;
import ch.powerunit.extensions.matchers.provideprocessor.extension.spotify.JsonStringSpotifyAutomatedExtension;
import ch.powerunit.extensions.matchers.provideprocessor.fields.AbstractFieldDescription;
import ch.powerunit.extensions.matchers.provideprocessor.fields.FieldDSLMethod;

public class RoundMirror extends AbstractRoundMirrorReferenceToProcessingEnv {

	private final Collection AUTOMATED_EXTENSIONS;
	private final Set elementsWithPM;
	private final Map, Set> elementsWithOtherAnnotations;
	private final Map alias = new HashMap<>();

	public RoundMirror(RoundEnvironment roundEnv, ProcessingEnvironment processingEnv) {
		super(roundEnv, processingEnv);
		this.elementsWithOtherAnnotations = new HashMap<>();
		this.elementsWithPM = roundEnv.getElementsAnnotatedWith(ProvideMatchers.class);
		elementsWithOtherAnnotations.put(IgnoreInMatcher.class,
				roundEnv.getElementsAnnotatedWith(IgnoreInMatcher.class));
		elementsWithOtherAnnotations.put(AddToMatcher.class, roundEnv.getElementsAnnotatedWith(AddToMatcher.class));
		elementsWithOtherAnnotations.put(AddToMatchers.class, roundEnv.getElementsAnnotatedWith(AddToMatchers.class));
		AUTOMATED_EXTENSIONS = getDefaultExtension().stream().filter(AutomatedExtension::isPresent)
				.collect(collectingAndThen(toList(), Collections::unmodifiableList));
	}

	private final List getDefaultExtension() {
		return Arrays.asList(new LocalDateMatchersAutomatedExtension(this),
				new LocalDateTimeMatchersAutomatedExtension(this), new LocalTimeMatchersAutomatedExtension(this),
				new ZonedDateTimeMatchersAutomatedExtension(this),
				new CollectionHamcrestUtilityAutomatedExtension(this), new JsonStringSpotifyAutomatedExtension(this),
				new DefaultBeanMatchersAutomatedExtension(this));
	}

	public Collection parse() {
		ProvidesMatchersElementVisitor providesMatchersElementVisitor = new ProvidesMatchersElementVisitor(this);
		elementsWithPM.stream().filter(e -> roundEnv.getRootElements().contains(e))
				.map(e -> e.accept(providesMatchersElementVisitor, null)).filter(Optional::isPresent)
				.map(t -> new ProvidesMatchersAnnotatedElementMirror(t.get(), this))
				.forEach(a -> alias.put(a.getFullyQualifiedNameOfClassAnnotatedWithProvideMatcher(), a));

		doWarningforAllElements();
		return alias.values();
	}

	private void doWarningforAllElements() {
		elementsWithOtherAnnotations.entrySet().stream().forEach(e -> doWarningForElement(e.getValue(), e.getKey()));
	}

	private void doWarningForElement(Set elements, Class aa) {
		elements.stream()
				.forEach(e -> processingEnv.getMessager().printMessage(Kind.MANDATORY_WARNING,
						"Annotation @" + aa.getName()
								+ " not supported at this location ; The surrounding class is not annotated with @ProvideMatchers",
						e, findAnnotationMirrorFor(e, aa)));
	}

	private AnnotationMirror findAnnotationMirrorFor(Element e, Class aa) {
		String aaName = aa.getName().toString();
		return e.getAnnotationMirrors().stream()
				.filter(a -> a.getAnnotationType()
						.equals(processingEnv.getElementUtils().getTypeElement(aaName).asType()))
				.findAny().orElse(null);
	}

	public boolean removeFromIgnoreList(Element e) {
		return elementsWithOtherAnnotations.values().stream().map(t -> t.remove(e)).filter(t -> t).findAny()
				.orElse(false);
	}

	public ProvidesMatchersAnnotatedElementMirror getByName(String name) {
		return alias.get(name);
	}

	public boolean isInSameRound(Element t) {
		if (t == null) {
			return false;
		}
		TypeMirror tm = t.asType();
		return elementsWithPM.stream().filter(e -> processingEnv.getTypeUtils().isSameType(e.asType(), tm)).findAny()
				.isPresent();
	}

	public AnnotationMirror getProvideMatchersAnnotation(Element e) {
		TypeMirror pmtm = processingEnv.getElementUtils()
				.getTypeElement("ch.powerunit.extensions.matchers.ProvideMatchers").asType();
		return getProcessingEnv().getElementUtils().getAllAnnotationMirrors(e).stream()
				.filter(a -> a.getAnnotationType().equals(pmtm)).findAny().orElse(null);
	}

	public Collection> getDSLMethodFor(ProvidesMatchersAnnotatedElementData target) {
		return AUTOMATED_EXTENSIONS.stream().map(ae -> ae.accept(target)).flatMap(Collection::stream).collect(toList());
	}

	public Collection getFieldDSLMethodFor(AbstractFieldDescription target) {
		return AUTOMATED_EXTENSIONS.stream().map(ae -> ae.accept(target)).flatMap(Collection::stream).collect(toList());
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy