/**
* Copyright 2011-2017 Asakusa Framework Team.
*
* 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 com.asakusafw.operator;
import java.text.MessageFormat;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import javax.annotation.processing.Completion;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.Processor;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
import com.asakusafw.operator.util.Logger;
/**
* Abstract implementation of Asakusa operator annotation processor.
*/
public abstract class AbstractOperatorAnnotationProcessor implements Processor {
static final Logger LOG = Logger.get(AbstractOperatorAnnotationProcessor.class);
/**
* The current compile environment.
*/
protected volatile CompileEnvironment environment;
/**
* Creates a new instance.
*/
protected AbstractOperatorAnnotationProcessor() {
LOG.debug("creating operator annotation processor: {}", this); //$NON-NLS-1$
}
@Override
public final void init(ProcessingEnvironment processingEnv) {
LOG.debug("initializing operator annotation processor: {}", this); //$NON-NLS-1$
try {
this.environment = createCompileEnvironment(processingEnv);
} catch (RuntimeException e) {
processingEnv.getMessager().printMessage(
Diagnostic.Kind.ERROR,
MessageFormat.format(
Messages.getString("AbstractOperatorAnnotationProcessor.errorFailInitialize"), //$NON-NLS-1$
e.toString()));
LOG.error(Messages.getString("AbstractOperatorAnnotationProcessor.logFailInitialize"), e); //$NON-NLS-1$
} catch (LinkageError e) {
processingEnv.getMessager().printMessage(
Diagnostic.Kind.ERROR,
MessageFormat.format(
Messages.getString("AbstractOperatorAnnotationProcessor.errorFailLinkage"), //$NON-NLS-1$
e.toString()));
LOG.error(Messages.getString("AbstractOperatorAnnotationProcessor.logFailLinkage"), e); //$NON-NLS-1$
throw e;
}
}
/**
* Creates a compile environment for this processing (for testing).
* @param processingEnv current processing environment
* @return created environment
*/
protected abstract CompileEnvironment createCompileEnvironment(ProcessingEnvironment processingEnv);
@Override
public final Set<String> getSupportedOptions() {
return CompilerOption.getOptionNames(getSupportedFeatures());
}
/**
* Returns the supported features.
* @return the supported features
*/
protected Collection<? extends CompileEnvironment.Support> getSupportedFeatures() {
return Collections.emptySet();
}
@Override
public final SourceVersion getSupportedSourceVersion() {
return Constants.getSupportedSourceVersion();
}
@Override
public Iterable<? extends Completion> getCompletions(
Element element,
AnnotationMirror annotation,
ExecutableElement member,
String userText) {
return Collections.emptySet();
}
@Override
public final boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
if (environment == null) {
return false;
}
LOG.debug("starting operator annotation processor: {}", this); //$NON-NLS-1$
try {
if (annotations.isEmpty() == false) {
run(annotations, roundEnv);
}
} catch (RuntimeException e) {
environment.getProcessingEnvironment().getMessager().printMessage(
Diagnostic.Kind.ERROR,
MessageFormat.format(
Messages.getString("AbstractOperatorAnnotationProcessor.errorFailCompile"), //$NON-NLS-1$
e.toString()));
LOG.error(Messages.getString("AbstractOperatorAnnotationProcessor.logFailCompile"), e); //$NON-NLS-1$
}
return false;
}
/**
* Runs this annotation processor.
* @param annotations the target operator annotations
* @param roundEnv the processing round environment
*/
protected abstract void run(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv);
}