/*
* Copyright 2014 Lukas Krejci
*
* 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.revapi.java.transforms.annotations;
import java.io.Reader;
import java.util.LinkedHashMap;
import java.util.regex.Pattern;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import org.revapi.AnalysisContext;
import org.revapi.Difference;
import org.revapi.DifferenceTransform;
import org.revapi.java.spi.Code;
import org.revapi.java.spi.ElementPairVisitor;
import org.revapi.java.spi.JavaModelElement;
/**
* @author Lukas Krejci
* @since 0.1
*/
abstract class AbstractAnnotationPresenceCheck implements DifferenceTransform<JavaModelElement> {
protected AnalysisContext analysisContext;
private final String annotationQualifiedName;
private final Code transformedCode;
private final Pattern[] codes;
protected AbstractAnnotationPresenceCheck(String annotationQualifiedName, Code annotationCheckCode,
Code transformedCode) {
this.annotationQualifiedName = annotationQualifiedName;
this.transformedCode = transformedCode;
String regex = "^" + Pattern.quote(annotationCheckCode.code()) + "$";
codes = new Pattern[]{Pattern.compile(regex)};
}
@Nonnull
@Override
public Pattern[] getDifferenceCodePatterns() {
return codes;
}
@Nullable
@Override
public String[] getConfigurationRootPaths() {
return null;
}
@Nullable
@Override
public Reader getJSONSchema(@Nonnull String configurationRootPath) {
return null;
}
@Override
public void initialize(@Nonnull AnalysisContext analysisContext) {
this.analysisContext = analysisContext;
}
@Nullable
@Override
public Difference transform(@Nullable final JavaModelElement oldElement,
@Nullable final JavaModelElement newElement, @Nonnull final Difference difference) {
//we're checking for change of presence of an annotation on an element. Thus both the old and new version
//of the element must be non-null.
if (oldElement == null || newElement == null) {
return null;
}
String affectedAnnotation = difference.attachments.get("annotationType");
if (!annotationQualifiedName.equals(affectedAnnotation)) {
return difference;
}
return oldElement.getDeclaringElement().accept(new ElementPairVisitor<Difference>() {
@Override
protected Difference unmatchedAction(@Nonnull javax.lang.model.element.Element element,
@Nullable javax.lang.model.element.Element otherElement) {
return difference;
}
@Override
protected Difference visitType(@Nonnull TypeElement oldElement,
@Nonnull TypeElement newElement) {
return common();
}
@Override
protected Difference visitPackage(@Nonnull PackageElement element,
@Nonnull PackageElement otherElement) {
return common();
}
@Override
protected Difference visitVariable(@Nonnull VariableElement element,
@Nonnull VariableElement otherElement) {
return common();
}
@Override
protected Difference visitExecutable(@Nonnull ExecutableElement element,
@Nonnull ExecutableElement otherElement) {
return common();
}
private Difference common() {
return transformedCode.createDifference(analysisContext.getLocale(),
new LinkedHashMap<>(difference.attachments));
}
}, newElement.getDeclaringElement());
}
@Override
public void close() throws Exception {
}
}