#32 Loading model element processors via service loader

This commit is contained in:
Gunnar Morling 2013-06-29 13:51:37 +02:00
parent 502780c441
commit 53597469ad
8 changed files with 113 additions and 13 deletions

View File

@ -18,7 +18,12 @@
*/
package org.mapstruct.ap;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.ServiceLoader;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.ProcessingEnvironment;
@ -39,11 +44,7 @@ import org.mapstruct.Mappings;
import org.mapstruct.ap.model.Mapper;
import org.mapstruct.ap.model.Options;
import org.mapstruct.ap.model.ReportingPolicy;
import org.mapstruct.ap.processor.CdiComponentProcessor;
import org.mapstruct.ap.processor.DefaultModelElementProcessorContext;
import org.mapstruct.ap.processor.MapperCreationProcessor;
import org.mapstruct.ap.processor.MapperRenderingProcessor;
import org.mapstruct.ap.processor.MethodRetrievalProcessor;
import org.mapstruct.ap.processor.ModelElementProcessor;
import org.mapstruct.ap.processor.ModelElementProcessor.ProcessorContext;
@ -142,14 +143,31 @@ public class MappingProcessor extends AbstractProcessor {
return processor.process( context, mapperTypeElement, sourceElement );
}
//TODO Retrieve via service loader
/**
* Retrieves all model element processors, ordered by their priority value
* (with the method retrieval processor having the lowest priority value (1)
* and the code generation processor the highest priority value.
*
* @return A list with all model element processors.
*/
private Iterable<ModelElementProcessor<?, ?>> getProcessors() {
return Arrays.<ModelElementProcessor<?, ?>>asList(
new MethodRetrievalProcessor(),
new MapperCreationProcessor(),
new CdiComponentProcessor(),
new MapperRenderingProcessor()
);
// TODO Re-consider which class loader to use in case processors are
// loaded from other modules, too
@SuppressWarnings("rawtypes")
Iterator<ModelElementProcessor> processorIterator = ServiceLoader.load(
ModelElementProcessor.class,
MappingProcessor.class.getClassLoader()
)
.iterator();
List<ModelElementProcessor<?, ?>> processors = new ArrayList<ModelElementProcessor<?, ?>>();
while ( processorIterator.hasNext() ) {
processors.add( processorIterator.next() );
}
Collections.sort( processors, new ProcessorComparator() );
return processors;
}
private TypeElement asTypeElement(Element element) {
@ -163,4 +181,15 @@ public class MappingProcessor extends AbstractProcessor {
}, null
);
}
private static class ProcessorComparator implements Comparator<ModelElementProcessor<?, ?>> {
@Override
public int compare(ModelElementProcessor<?, ?> o1, ModelElementProcessor<?, ?> o2) {
return
o1.getPriority() < o2.getPriority() ? -1 :
o1.getPriority() == o2.getPriority() ? 0 :
1;
}
}
}

View File

@ -56,4 +56,9 @@ public class CdiComponentProcessor implements ModelElementProcessor<Mapper, Mapp
return mapper;
}
@Override
public int getPriority() {
return 1100;
}
}

View File

@ -93,6 +93,12 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Metho
return getMapper( mapperTypeElement, sourceElement );
}
@Override
public int getPriority() {
return 1000;
}
private Mapper getMapper(TypeElement element, List<Method> methods) {
ReportingPolicy unmappedTargetPolicy = getEffectiveUnmappedTargetPolicy( element );
List<MappingMethod> mappingMethods = getMappingMethods( methods, unmappedTargetPolicy );

View File

@ -55,4 +55,9 @@ public class MapperRenderingProcessor implements ModelElementProcessor<Mapper, V
new ModelWriter().writeModel( sourceFile, model );
}
@Override
public int getPriority() {
return 10000;
}
}

View File

@ -68,6 +68,11 @@ public class MethodRetrievalProcessor implements ModelElementProcessor<TypeEleme
return retrieveMethods( mapperTypeElement, true );
}
@Override
public int getPriority() {
return 1;
}
/**
* Retrieves the mapping methods declared by the given mapper type.
*

View File

@ -77,4 +77,16 @@ public interface ModelElementProcessor<P, R> {
* generates the resulting Java source file.
*/
R process(ProcessorContext context, TypeElement mapperTypeElement, P sourceElement);
/**
* Returns the priority value of this processor which must be between 1
* (highest priority) and 10000 (lowest priority). Processors are invoked in
* order from highest to lowest priority, starting with the mapping method
* retrieval processor (priority 1) and finishing with the code generation
* processor (priority 10000). Processors working on the built
* {@code Mapper} model must have a priority > 1000.
*
* @return The priority value of this processor.
*/
int getPriority();
}

View File

@ -1 +1,18 @@
org.mapstruct.ap.MappingProcessor
# Copyright 2012-2013 Gunnar Morling (http://www.gunnarmorling.de/)
# and/or other contributors as indicated by the @authors tag. See the
# copyright.txt file in the distribution for a full listing of all
# contributors.
#
# 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.
org.mapstruct.ap.MappingProcessor

View File

@ -0,0 +1,21 @@
# Copyright 2012-2013 Gunnar Morling (http://www.gunnarmorling.de/)
# and/or other contributors as indicated by the @authors tag. See the
# copyright.txt file in the distribution for a full listing of all
# contributors.
#
# 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.
org.mapstruct.ap.processor.CdiComponentProcessor
org.mapstruct.ap.processor.MapperCreationProcessor
org.mapstruct.ap.processor.MapperRenderingProcessor
org.mapstruct.ap.processor.MethodRetrievalProcessor