mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#109 Breaking up cycle between "model" and "writer" packages by introducing Writable interface
This commit is contained in:
parent
21ed656348
commit
4d4f55a162
@ -1,39 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2012-2014 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.
|
|
||||||
*/
|
|
||||||
package org.mapstruct.ap.model;
|
|
||||||
|
|
||||||
import java.io.Writer;
|
|
||||||
|
|
||||||
import org.mapstruct.ap.writer.FreeMarkerModelElementWriter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default implementation of {@link ModelElement} which writes model elements
|
|
||||||
* using FreeMarker templates. By default, the fully-qualified class name of the
|
|
||||||
* given model element type, appended with the extension {@code *.ftl} is used
|
|
||||||
* as template file name.
|
|
||||||
*
|
|
||||||
* @author Gunnar Morling
|
|
||||||
*/
|
|
||||||
public abstract class AbstractModelElement implements ModelElement {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void write(Context context, Writer writer) throws Exception {
|
|
||||||
new FreeMarkerModelElementWriter().write( this, context, writer );
|
|
||||||
}
|
|
||||||
}
|
|
@ -18,13 +18,17 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapstruct.ap.model;
|
package org.mapstruct.ap.model;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.mapstruct.ap.util.Collections;
|
/**
|
||||||
|
* Represents a Java 5 annotation.
|
||||||
|
*
|
||||||
|
* @author Gunnar Morling
|
||||||
|
*/
|
||||||
|
public class Annotation extends ModelElement {
|
||||||
|
|
||||||
public class Annotation extends AbstractModelElement {
|
private final Type type;
|
||||||
|
|
||||||
private Type type;
|
|
||||||
|
|
||||||
public Annotation(Type type) {
|
public Annotation(Type type) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
@ -36,6 +40,6 @@ public class Annotation extends AbstractModelElement {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Type> getImportTypes() {
|
public Set<Type> getImportTypes() {
|
||||||
return Collections.asSet( type );
|
return Collections.singleton( type );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ import org.mapstruct.ap.util.Strings;
|
|||||||
* @author Gunnar Morling
|
* @author Gunnar Morling
|
||||||
* @author Andreas Gudian
|
* @author Andreas Gudian
|
||||||
*/
|
*/
|
||||||
public class AnnotationMapperReference extends AbstractModelElement implements MapperReference {
|
public class AnnotationMapperReference extends MapperReference {
|
||||||
|
|
||||||
private final Annotation annotation;
|
private final Annotation annotation;
|
||||||
private final Type type;
|
private final Type type;
|
||||||
|
@ -31,7 +31,7 @@ import org.mapstruct.ap.util.TypeFactory;
|
|||||||
*
|
*
|
||||||
* @author Gunnar Morling
|
* @author Gunnar Morling
|
||||||
*/
|
*/
|
||||||
public class DefaultMapperReference extends AbstractModelElement implements MapperReference {
|
public class DefaultMapperReference extends MapperReference {
|
||||||
|
|
||||||
private final Type type;
|
private final Type type;
|
||||||
private final boolean isAnnotatedMapper;
|
private final boolean isAnnotatedMapper;
|
||||||
|
@ -23,7 +23,6 @@ import java.util.Collection;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.SortedSet;
|
import java.util.SortedSet;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
|
|
||||||
import javax.annotation.Generated;
|
import javax.annotation.Generated;
|
||||||
import javax.lang.model.element.ElementKind;
|
import javax.lang.model.element.ElementKind;
|
||||||
import javax.lang.model.element.TypeElement;
|
import javax.lang.model.element.TypeElement;
|
||||||
@ -37,7 +36,7 @@ import org.mapstruct.ap.util.TypeFactory;
|
|||||||
*
|
*
|
||||||
* @author Gunnar Morling
|
* @author Gunnar Morling
|
||||||
*/
|
*/
|
||||||
public class Mapper extends AbstractModelElement {
|
public class Mapper extends ModelElement {
|
||||||
|
|
||||||
private static final String IMPLEMENTATION_SUFFIX = "Impl";
|
private static final String IMPLEMENTATION_SUFFIX = "Impl";
|
||||||
|
|
||||||
|
@ -19,12 +19,16 @@
|
|||||||
package org.mapstruct.ap.model;
|
package org.mapstruct.ap.model;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A reference to another mapper class, which itself may be generated or
|
* A reference to another mapper class, which itself may be generated or hand-written.
|
||||||
* hand-written.
|
|
||||||
*
|
*
|
||||||
* @author Gunnar Morling
|
* @author Gunnar Morling
|
||||||
*/
|
*/
|
||||||
public interface MapperReference extends ModelElement {
|
public abstract class MapperReference extends ModelElement {
|
||||||
|
|
||||||
Type getMapperType();
|
/**
|
||||||
|
* Returns the type of the referenced mapper
|
||||||
|
*
|
||||||
|
* @return the type of the referenced mapper
|
||||||
|
*/
|
||||||
|
public abstract Type getMapperType();
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ import org.mapstruct.ap.util.Strings;
|
|||||||
*
|
*
|
||||||
* @author Gunnar Morling
|
* @author Gunnar Morling
|
||||||
*/
|
*/
|
||||||
public abstract class MappingMethod extends AbstractModelElement {
|
public abstract class MappingMethod extends ModelElement {
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
private final List<Parameter> parameters;
|
private final List<Parameter> parameters;
|
||||||
|
@ -21,47 +21,30 @@ package org.mapstruct.ap.model;
|
|||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.mapstruct.ap.writer.FreeMarkerModelElementWriter;
|
||||||
|
import org.mapstruct.ap.writer.Writable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A model element with the ability to write itself into a given {@link Writer}.
|
* Base class of all model elements.
|
||||||
|
* <p>
|
||||||
|
* Implements the {@link Writable} contract to write model elements into source code files using FreeMarker templates.
|
||||||
|
* By default, the fully-qualified class name of the given model element type, appended with the extension {@code *.ftl}
|
||||||
|
* is used as template file name.
|
||||||
*
|
*
|
||||||
* @author Gunnar Morling
|
* @author Gunnar Morling
|
||||||
*/
|
*/
|
||||||
public interface ModelElement {
|
public abstract class ModelElement implements Writable {
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Passed to {@link ModelElement}, providing access to additional data
|
public void write(Context context, Writer writer) throws Exception {
|
||||||
* specific to a given implementation of the model serialization mechanism.
|
new FreeMarkerModelElementWriter().write( this, context, writer );
|
||||||
*
|
|
||||||
* @author Gunnar Morling
|
|
||||||
*/
|
|
||||||
interface Context {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the object with the given type from this context.
|
|
||||||
*
|
|
||||||
* @param type The type of the object to retrieve from this context.
|
|
||||||
*
|
|
||||||
* @return The object with the given type from this context.
|
|
||||||
*/
|
|
||||||
<T> T get(Class<T> type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes this model element to the given writer.
|
* Returns a set containing those {@link Type}s referenced by this model element for which an import statement needs
|
||||||
|
* to be declared.
|
||||||
*
|
*
|
||||||
* @param context Provides additional data specific to the used implementation
|
* @return A set with type referenced by this model element. Must not be {@code null}.
|
||||||
* of the model serialization mechanism.
|
|
||||||
* @param writer The writer to write this model to. Must not be closed by
|
|
||||||
* implementations.
|
|
||||||
*/
|
*/
|
||||||
void write(Context context, Writer writer) throws Exception;
|
public abstract Set<Type> getImportTypes();
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a set containing those {@link Type}s referenced by this model
|
|
||||||
* element for which an import statement needs to be declared.
|
|
||||||
*
|
|
||||||
* @return A set with type referenced by this model element. Must not be
|
|
||||||
* {@code null.}
|
|
||||||
*/
|
|
||||||
Set<Type> getImportTypes();
|
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ import org.mapstruct.ap.util.Collections;
|
|||||||
*
|
*
|
||||||
* @author Gunnar Morling
|
* @author Gunnar Morling
|
||||||
*/
|
*/
|
||||||
public class Parameter extends AbstractModelElement {
|
public class Parameter extends ModelElement {
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
private final Type type;
|
private final Type type;
|
||||||
|
@ -29,7 +29,7 @@ import java.util.Set;
|
|||||||
*
|
*
|
||||||
* @author Gunnar Morling
|
* @author Gunnar Morling
|
||||||
*/
|
*/
|
||||||
public class PropertyMapping extends AbstractModelElement {
|
public class PropertyMapping extends ModelElement {
|
||||||
|
|
||||||
private final String sourceBeanName;
|
private final String sourceBeanName;
|
||||||
private final String sourceName;
|
private final String sourceName;
|
||||||
|
@ -43,7 +43,7 @@ import org.mapstruct.ap.util.TypeFactory;
|
|||||||
*
|
*
|
||||||
* @author Gunnar Morling
|
* @author Gunnar Morling
|
||||||
*/
|
*/
|
||||||
public class Type extends AbstractModelElement implements Comparable<Type> {
|
public class Type extends ModelElement implements Comparable<Type> {
|
||||||
|
|
||||||
private final String packageName;
|
private final String packageName;
|
||||||
private final String name;
|
private final String name;
|
||||||
|
@ -28,7 +28,7 @@ import java.util.Set;
|
|||||||
*
|
*
|
||||||
* @author Gunnar Morling
|
* @author Gunnar Morling
|
||||||
*/
|
*/
|
||||||
public class TypeConversion extends AbstractModelElement {
|
public class TypeConversion extends ModelElement {
|
||||||
|
|
||||||
private final Set<Type> importTypes;
|
private final Set<Type> importTypes;
|
||||||
private final List<Type> exceptionTypes;
|
private final List<Type> exceptionTypes;
|
||||||
|
@ -29,11 +29,10 @@ import freemarker.template.Template;
|
|||||||
import freemarker.template.TemplateHashModel;
|
import freemarker.template.TemplateHashModel;
|
||||||
import freemarker.template.TemplateModel;
|
import freemarker.template.TemplateModel;
|
||||||
import freemarker.template.TemplateModelException;
|
import freemarker.template.TemplateModelException;
|
||||||
import org.mapstruct.ap.model.ModelElement;
|
import org.mapstruct.ap.writer.Writable.Context;
|
||||||
import org.mapstruct.ap.model.ModelElement.Context;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delegate for writing given {@link ModelElement}s into a {@link Writer} using
|
* Delegate for writing given {@link Writable}s into a {@link Writer} using
|
||||||
* FreeMarker templates. Any parameters passed to the
|
* FreeMarker templates. Any parameters passed to the
|
||||||
* {@link ModelIncludeDirective} in addition to element itself can be accessed
|
* {@link ModelIncludeDirective} in addition to element itself can be accessed
|
||||||
* from within the template using the {@code ext} pseudo-element.
|
* from within the template using the {@code ext} pseudo-element.
|
||||||
@ -42,16 +41,16 @@ import org.mapstruct.ap.model.ModelElement.Context;
|
|||||||
*/
|
*/
|
||||||
public class FreeMarkerModelElementWriter {
|
public class FreeMarkerModelElementWriter {
|
||||||
|
|
||||||
public void write(ModelElement modelElement, Context context, Writer writer) throws Exception {
|
public void write(Writable writable, Context context, Writer writer) throws Exception {
|
||||||
write( modelElement, modelElement.getClass().getName() + ".ftl", context, writer );
|
write( writable, writable.getClass().getName() + ".ftl", context, writer );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void write(ModelElement modelElement, String templateName, Context context, Writer writer) throws Exception {
|
public void write(Writable writable, String templateName, Context context, Writer writer) throws Exception {
|
||||||
Configuration configuration = context.get( Configuration.class );
|
Configuration configuration = context.get( Configuration.class );
|
||||||
Template template = configuration.getTemplate( templateName );
|
Template template = configuration.getTemplate( templateName );
|
||||||
template.process(
|
template.process(
|
||||||
new ExternalParamsTemplateModel(
|
new ExternalParamsTemplateModel(
|
||||||
new BeanModel( modelElement, BeansWrapper.getDefaultInstance() ),
|
new BeanModel( writable, BeansWrapper.getDefaultInstance() ),
|
||||||
new SimpleMapModel( context.get( Map.class ), BeansWrapper.getDefaultInstance() )
|
new SimpleMapModel( context.get( Map.class ), BeansWrapper.getDefaultInstance() )
|
||||||
),
|
),
|
||||||
writer
|
writer
|
||||||
|
@ -29,12 +29,11 @@ import freemarker.template.TemplateDirectiveBody;
|
|||||||
import freemarker.template.TemplateDirectiveModel;
|
import freemarker.template.TemplateDirectiveModel;
|
||||||
import freemarker.template.TemplateException;
|
import freemarker.template.TemplateException;
|
||||||
import freemarker.template.TemplateModel;
|
import freemarker.template.TemplateModel;
|
||||||
import org.mapstruct.ap.model.ModelElement;
|
|
||||||
import org.mapstruct.ap.writer.ModelWriter.DefaultModelElementWriterContext;
|
import org.mapstruct.ap.writer.ModelWriter.DefaultModelElementWriterContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link TemplateDirectiveModel} which allows to recursively write a graph of
|
* A {@link TemplateDirectiveModel} which allows to recursively write a graph of
|
||||||
* {@link ModelElement}s, with each element using its own template. Elements are
|
* {@link Writable}s, with each element using its own template. Elements are
|
||||||
* imported into the parent template by using this directive like so:
|
* imported into the parent template by using this directive like so:
|
||||||
* {@code <@includeModel object=myProperty/>}.
|
* {@code <@includeModel object=myProperty/>}.
|
||||||
*
|
*
|
||||||
@ -53,7 +52,7 @@ public class ModelIncludeDirective implements TemplateDirectiveModel {
|
|||||||
TemplateDirectiveBody body)
|
TemplateDirectiveBody body)
|
||||||
throws TemplateException, IOException {
|
throws TemplateException, IOException {
|
||||||
|
|
||||||
ModelElement modelElement = getModelElement( params );
|
Writable modelElement = getModelElement( params );
|
||||||
DefaultModelElementWriterContext context = createContext( params );
|
DefaultModelElementWriterContext context = createContext( params );
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -74,7 +73,7 @@ public class ModelIncludeDirective implements TemplateDirectiveModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
private ModelElement getModelElement(Map params) {
|
private Writable getModelElement(Map params) {
|
||||||
if ( !params.containsKey( "object" ) ) {
|
if ( !params.containsKey( "object" ) ) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Object to be included must be passed to this directive via the 'object' parameter"
|
"Object to be included must be passed to this directive via the 'object' parameter"
|
||||||
@ -89,11 +88,11 @@ public class ModelIncludeDirective implements TemplateDirectiveModel {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !( objectModel.getWrappedObject() instanceof ModelElement ) ) {
|
if ( !( objectModel.getWrappedObject() instanceof Writable ) ) {
|
||||||
throw new IllegalArgumentException( "Given object isn't a ModelElement:" + objectModel.getWrappedObject() );
|
throw new IllegalArgumentException( "Given object isn't a ModelElement:" + objectModel.getWrappedObject() );
|
||||||
}
|
}
|
||||||
|
|
||||||
return (ModelElement) objectModel.getWrappedObject();
|
return (Writable) objectModel.getWrappedObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -26,8 +26,7 @@ import javax.tools.JavaFileObject;
|
|||||||
import freemarker.log.Logger;
|
import freemarker.log.Logger;
|
||||||
import freemarker.template.Configuration;
|
import freemarker.template.Configuration;
|
||||||
import freemarker.template.DefaultObjectWrapper;
|
import freemarker.template.DefaultObjectWrapper;
|
||||||
import org.mapstruct.ap.model.ModelElement;
|
import org.mapstruct.ap.writer.Writable.Context;
|
||||||
import org.mapstruct.ap.model.ModelElement.Context;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes Java source files based on given mapper models, using a FreeMarker
|
* Writes Java source files based on given mapper models, using a FreeMarker
|
||||||
@ -60,7 +59,7 @@ public class ModelWriter {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeModel(JavaFileObject sourceFile, ModelElement model) {
|
public void writeModel(JavaFileObject sourceFile, Writable model) {
|
||||||
try {
|
try {
|
||||||
BufferedWriter writer = new BufferedWriter( new IndentationCorrectingWriter( sourceFile.openWriter() ) );
|
BufferedWriter writer = new BufferedWriter( new IndentationCorrectingWriter( sourceFile.openWriter() ) );
|
||||||
|
|
||||||
|
@ -0,0 +1,55 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2012-2014 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.
|
||||||
|
*/
|
||||||
|
package org.mapstruct.ap.writer;
|
||||||
|
|
||||||
|
import java.io.Writer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An element with the ability to write itself into a given {@link Writer}.
|
||||||
|
*
|
||||||
|
* @author Gunnar Morling
|
||||||
|
*/
|
||||||
|
public interface Writable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Passed to {@link Writable}, providing access to additional data specific to a given implementation of the model
|
||||||
|
* serialization mechanism.
|
||||||
|
*
|
||||||
|
* @author Gunnar Morling
|
||||||
|
*/
|
||||||
|
interface Context {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the object with the given type from this context.
|
||||||
|
*
|
||||||
|
* @param type The type of the object to retrieve from this context.
|
||||||
|
*
|
||||||
|
* @return The object with the given type from this context.
|
||||||
|
*/
|
||||||
|
<T> T get(Class<T> type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes this element to the given writer.
|
||||||
|
*
|
||||||
|
* @param context Provides additional data specific to the used implementation of the serialization mechanism.
|
||||||
|
* @param writer The writer to write this element to. Must not be closed by implementations.
|
||||||
|
*/
|
||||||
|
void write(Context context, Writer writer) throws Exception;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user