More efficient access when DTOs are used in template models.

This commit is contained in:
Michael Lipp 2023-05-28 16:34:08 +02:00
parent 11452babe6
commit 2ed51772ed
5 changed files with 98 additions and 18 deletions

View file

@ -1,5 +1,5 @@
#
#Tue May 23 17:52:06 CEST 2023
#Sun May 28 16:23:45 CEST 2023
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
@ -286,9 +286,9 @@ org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=1
org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines
org.eclipse.jdt.core.formatter.lineSplit=80
org.eclipse.jdt.core.compiler.source=17
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
org.eclipse.jdt.core.formatter.tabulation.size=4
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position=false
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
@ -304,13 +304,13 @@ org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
eclipse.preferences.version=1
org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
eclipse.preferences.version=1
org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
org.eclipse.jdt.core.compiler.compliance=17
org.eclipse.jdt.core.formatter.blank_lines_after_package=1
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16

View file

@ -9,6 +9,5 @@ plugins {
}
dependencies {
implementation 'com.fasterxml.jackson.core:jackson-databind:[2.15.0,3]'
implementation 'org.freemarker:freemarker:[2.3.32,2.4)'
}

View file

@ -18,6 +18,15 @@
package org.jdrupes.vmoperator.util;
/**
* Marks a class as the definition of a data transfer object.
* DTOs have public attributes and usually no behavior (though
* the can have e.g. methods for checking the consistency.
*
* The DTO marker affects the conversion of objects to other
* representations.
*/
@SuppressWarnings("PMD.ShortClassName")
public interface Dto {
}

View file

@ -0,0 +1,72 @@
/*
* VM-Operator
* Copyright (C) 2023 Michael N. Lipp
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.jdrupes.vmoperator.util;
import freemarker.ext.util.WrapperTemplateModel;
import freemarker.template.ObjectWrapper;
import freemarker.template.TemplateHashModel;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
import freemarker.template.WrappingTemplateModel;
/**
* Wraps a DTO in a {@link TemplateHashModel}.
*/
public class DtoTemplateModel extends WrappingTemplateModel
implements WrapperTemplateModel, TemplateHashModel {
private final Dto dto;
/**
* Instantiates a new DTO template model.
*
* @param objectWrapper the object wrapper
* @param dto the dto
*/
public DtoTemplateModel(ObjectWrapper objectWrapper, Dto dto) {
super(objectWrapper);
this.dto = dto;
}
@Override
@SuppressWarnings("PMD.PreserveStackTrace")
public TemplateModel get(String key) throws TemplateModelException {
try {
var field = dto.getClass().getDeclaredField(key);
return wrap(field.get(dto));
} catch (NoSuchFieldException | SecurityException e) {
throw new TemplateModelException("No Field " + key
+ " in class " + dto.getClass());
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new TemplateModelException("Cannot access field " + key
+ " in class " + dto.getClass());
}
}
@Override
public boolean isEmpty() throws TemplateModelException {
return false;
}
@Override
public Object getWrappedObject() {
return dto;
}
}

View file

@ -18,31 +18,31 @@
package org.jdrupes.vmoperator.util;
import com.fasterxml.jackson.databind.ObjectMapper;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
import freemarker.template.Version;
import java.util.Map;
/**
* Provides an object wrapper that handles {@link Dto}s.
*/
public class ExtendedObjectWrapper extends DefaultObjectWrapper {
private ObjectMapper mapper;
public ExtendedObjectWrapper(Version incompatibleImprovements,
ObjectMapper mapper) {
/**
* Instantiates a new extended object wrapper.
*
* @param incompatibleImprovements the incompatible improvements
*/
public ExtendedObjectWrapper(Version incompatibleImprovements) {
super(incompatibleImprovements);
this.mapper = mapper;
}
@Override
protected TemplateModel handleUnknownType(final Object obj)
throws TemplateModelException {
if (obj instanceof Dto) {
var asMap = mapper.convertValue(obj, Map.class);
return this.wrap(asMap);
if (obj instanceof Dto dto) {
return new DtoTemplateModel(this, dto);
}
return super.handleUnknownType(obj);
}
}