mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#32 Preparing aggregated model to allow nodes to write out themselves using specific templates
This commit is contained in:
parent
522c9e851a
commit
781f698a8a
@ -130,8 +130,7 @@ public class MapperGenerationVisitor extends ElementKindVisitor6<Void, Void> {
|
||||
throw new RuntimeException( e );
|
||||
}
|
||||
|
||||
ModelWriter modelWriter = new ModelWriter( "mapper-implementation.ftl" );
|
||||
modelWriter.writeModel( sourceFile, model );
|
||||
new ModelWriter().writeModel( sourceFile, model );
|
||||
}
|
||||
|
||||
private Mapper retrieveModel(TypeElement element) {
|
||||
|
@ -0,0 +1,39 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
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 class AbstractModelElement implements ModelElement {
|
||||
|
||||
@Override
|
||||
public void write(Context context, Writer writer) throws Exception {
|
||||
new FreeMarkerModelElementWriter().write( this, context, writer );
|
||||
}
|
||||
}
|
@ -24,7 +24,7 @@ import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
import javax.annotation.Generated;
|
||||
|
||||
public class Mapper {
|
||||
public class Mapper extends AbstractModelElement {
|
||||
|
||||
private final String packageName;
|
||||
private final String interfaceName;
|
||||
|
@ -0,0 +1,57 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.mapstruct.ap.model;
|
||||
|
||||
import java.io.Writer;
|
||||
|
||||
/**
|
||||
* A model element with the ability to write itself into a given {@link Writer}.
|
||||
*
|
||||
* @author Gunnar Morling
|
||||
*/
|
||||
public interface ModelElement {
|
||||
|
||||
/**
|
||||
* Passed to {@link ModelElement}, 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 model element to the given writer.
|
||||
*
|
||||
* @param context Provides additional data specific to the used implementation
|
||||
* 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;
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.mapstruct.ap.writer;
|
||||
|
||||
import java.io.Writer;
|
||||
|
||||
import freemarker.template.Configuration;
|
||||
import freemarker.template.Template;
|
||||
import org.mapstruct.ap.model.ModelElement;
|
||||
import org.mapstruct.ap.model.ModelElement.Context;
|
||||
|
||||
/**
|
||||
* Delegate for writing given {@link ModelElements} into a {@link Writer} using
|
||||
* FreeMarker templates.
|
||||
*
|
||||
* @author Gunnar Morling
|
||||
*/
|
||||
public class FreeMarkerModelElementWriter {
|
||||
|
||||
public void write(ModelElement modelElement, Context context, Writer writer) throws Exception {
|
||||
write( modelElement, modelElement.getClass().getName() + ".ftl", context, writer );
|
||||
}
|
||||
|
||||
public void write(ModelElement modelElement, String templateName, Context context, Writer writer) throws Exception {
|
||||
Configuration configuration = context.get( Configuration.class );
|
||||
|
||||
Template template = configuration.getTemplate( templateName );
|
||||
template.process( modelElement, writer );
|
||||
}
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.mapstruct.ap.writer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import freemarker.core.Environment;
|
||||
import freemarker.ext.beans.BeanModel;
|
||||
import freemarker.template.TemplateDirectiveBody;
|
||||
import freemarker.template.TemplateDirectiveModel;
|
||||
import freemarker.template.TemplateException;
|
||||
import freemarker.template.TemplateModel;
|
||||
import org.mapstruct.ap.model.ModelElement;
|
||||
import org.mapstruct.ap.writer.ModelWriter.DefaultModelElementWriterContext;
|
||||
|
||||
/**
|
||||
* A {@link TemplateDirectiveModel} which allows to recursively write a graph of
|
||||
* {@link ModelElement}s, with each element using its own template. Elements are
|
||||
* imported into the parent template by using this directive like so:
|
||||
* {@code <@includeModel object=myProperty/>}.
|
||||
*
|
||||
* @author Gunnar Morling
|
||||
*/
|
||||
public class ModelIncludeDirective implements TemplateDirectiveModel {
|
||||
|
||||
private DefaultModelElementWriterContext context;
|
||||
|
||||
public ModelIncludeDirective(DefaultModelElementWriterContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Environment env, @SuppressWarnings("rawtypes") Map params, TemplateModel[] loopVars,
|
||||
TemplateDirectiveBody body)
|
||||
throws TemplateException, IOException {
|
||||
|
||||
Object wrappedObject = ( (BeanModel) params.get( "object" ) ).getWrappedObject();
|
||||
|
||||
if ( !( wrappedObject instanceof ModelElement ) ) {
|
||||
throw new IllegalArgumentException( "Given object isn't a ModelElement:" + wrappedObject );
|
||||
}
|
||||
|
||||
ModelElement modelElement = (ModelElement) wrappedObject;
|
||||
|
||||
try {
|
||||
modelElement.write( context, env.getOut() );
|
||||
}
|
||||
catch ( TemplateException te ) {
|
||||
throw te;
|
||||
}
|
||||
catch ( IOException ioe ) {
|
||||
throw ioe;
|
||||
}
|
||||
catch ( RuntimeException re ) {
|
||||
throw re;
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
throw new RuntimeException( e );
|
||||
}
|
||||
}
|
||||
}
|
@ -19,11 +19,14 @@
|
||||
package org.mapstruct.ap.writer;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.tools.JavaFileObject;
|
||||
|
||||
import freemarker.template.Configuration;
|
||||
import freemarker.template.DefaultObjectWrapper;
|
||||
import freemarker.template.Template;
|
||||
import org.mapstruct.ap.model.ModelElement;
|
||||
import org.mapstruct.ap.model.ModelElement.Context;
|
||||
|
||||
/**
|
||||
* Writes Java source files based on given mapper models, using a FreeMarker
|
||||
@ -39,25 +42,22 @@ public class ModelWriter {
|
||||
*/
|
||||
private static final Configuration CONFIGURATION;
|
||||
|
||||
private final String templateName;
|
||||
|
||||
static {
|
||||
CONFIGURATION = new Configuration();
|
||||
CONFIGURATION.setClassForTemplateLoading( ModelWriter.class, "/" );
|
||||
CONFIGURATION.setObjectWrapper( new DefaultObjectWrapper() );
|
||||
CONFIGURATION.setSharedVariable(
|
||||
"includeModel",
|
||||
new ModelIncludeDirective( new DefaultModelElementWriterContext( CONFIGURATION ) )
|
||||
);
|
||||
}
|
||||
|
||||
public ModelWriter(String templateName) {
|
||||
this.templateName = templateName;
|
||||
}
|
||||
|
||||
public void writeModel(JavaFileObject sourceFile, Object model) {
|
||||
|
||||
public void writeModel(JavaFileObject sourceFile, ModelElement model) {
|
||||
try {
|
||||
BufferedWriter writer = new BufferedWriter( sourceFile.openWriter() );
|
||||
|
||||
Template template = CONFIGURATION.getTemplate( templateName );
|
||||
template.process( model, writer );
|
||||
model.write( new DefaultModelElementWriterContext( CONFIGURATION ), writer );
|
||||
|
||||
writer.flush();
|
||||
writer.close();
|
||||
}
|
||||
@ -68,4 +68,25 @@ public class ModelWriter {
|
||||
throw new RuntimeException( e );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Context} implementation which provides access to the current
|
||||
* FreeMarker {@link Configuration}.
|
||||
*
|
||||
* @author Gunnar Morling
|
||||
*/
|
||||
static class DefaultModelElementWriterContext implements Context {
|
||||
|
||||
private Map<Class<?>, Object> values = new HashMap<Class<?>, Object>();
|
||||
|
||||
private DefaultModelElementWriterContext(Configuration configuration) {
|
||||
values.put( Configuration.class, configuration );
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T get(Class<T> type) {
|
||||
return (T) values.get( type );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user