| #* |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you 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. |
| *# |
| #parse ( "common.vm" ) |
| # |
| #set ( $package = "${packageToolV4}" ) |
| #set ( $className = "${model.name}Transformer" ) |
| # |
| #MODELLO-VELOCITY#SAVE-OUTPUT-TO ${package.replace('.','/')}/${className}.java |
| // =================== DO NOT EDIT THIS FILE ==================== |
| // Generated by Modello Velocity from ${template} |
| // template, any modifications will be overwritten. |
| // ============================================================== |
| package ${package}; |
| |
| import java.io.ObjectStreamException; |
| import java.util.AbstractList; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.LinkedHashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Properties; |
| import java.util.Objects; |
| import java.util.function.BinaryOperator; |
| import java.util.function.UnaryOperator; |
| import java.util.function.Supplier; |
| import java.util.stream.Collectors; |
| |
| import org.apache.maven.api.annotations.Generated; |
| import org.apache.maven.api.xml.XmlNode; |
| #foreach ( $class in $model.allClasses ) |
| import ${packageModelV4}.${class.name}; |
| #end |
| |
| @Generated |
| public class ${className} { |
| |
| private final UnaryOperator<String> transformer; |
| |
| public ${className}(UnaryOperator<String> transformer) { |
| this.transformer = transformer; |
| } |
| |
| /** |
| * Transforms the given model |
| */ |
| public ${root.name} visit(${root.name} target) { |
| Objects.requireNonNull(target, "target cannot be null"); |
| return transform${root.name}(target); |
| } |
| |
| /** |
| * The transformation function. |
| */ |
| protected String transform(String value) { |
| return transformer.apply(value); |
| } |
| |
| #foreach ( $class in $model.allClasses ) |
| #if ( $class.name != "InputSource" && $class.name != "InputLocation" ) |
| #set ( $ancestors = $Helper.ancestors( $class ) ) |
| #set ( $allFields = $Helper.xmlFields( $class ) ) |
| protected ${class.name} transform${class.name}(${class.name} target) { |
| if (target == null) { |
| return null; |
| } |
| Supplier<${class.name}.Builder> creator = () -> ${class.name}.newBuilder(target); |
| ${class.name}.Builder builder = null; |
| #foreach ( $field in $allFields ) |
| builder = (${class.name}.Builder) transform${field.modelClass.name}_${Helper.capitalise($field.name)}(creator, builder, target); |
| #end |
| return builder != null ? builder.build() : target; |
| } |
| |
| #foreach ( $field in $allFields ) |
| #set ( $capField = ${Helper.capitalise($field.name)} ) |
| protected ${class.name}.Builder transform${class.name}_${capField}(Supplier<? extends ${class.name}.Builder> creator, ${class.name}.Builder builder, ${class.name} target) { |
| #if ( $field.type == "String" ) |
| String oldVal = target.get${capField}(); |
| String newVal = transform(oldVal); |
| return newVal != oldVal ? (builder != null ? builder : creator.get()).${field.name}(newVal) : builder; |
| #elseif ( $field.type == "java.util.List" && $field.to == "String" && $field.multiplicity == "*" ) |
| List<String> oldVal = target.get${capField}(); |
| List<String> newVal = transform(oldVal, this::transform); |
| return newVal != oldVal ? (builder != null ? builder : creator.get()).${field.name}(newVal) : builder; |
| #elseif ( $field.type == "java.util.Properties" && $field.to == "String" && $field.multiplicity == "*" ) |
| Map<String, String> props = target.get${capField}(); |
| Map<String, String> newProps = null; |
| for (Map.Entry<String, String> entry : props.entrySet()) { |
| String newVal = transform(entry.getValue()); |
| if (newVal != null && newVal != entry.getValue()) { |
| if (newProps == null) { |
| newProps = new HashMap<>(); |
| newProps.putAll(props); |
| builder = builder != null ? builder : creator.get(); |
| builder.${field.name}(newProps); |
| } |
| newProps.put(entry.getKey(), newVal); |
| } |
| } |
| return builder; |
| #elseif ( $field.to && $field.multiplicity == "1" ) |
| ${field.to} oldVal = target.get${capField}(); |
| ${field.to} newVal = transform${field.to}(oldVal); |
| return newVal != oldVal ? (builder != null ? builder : creator.get()).${field.name}(newVal) : builder; |
| #elseif ( $field.to && $field.multiplicity == "*" ) |
| List<${field.to}> oldVal = target.get${capField}(); |
| List<${field.to}> newVal = transform(oldVal, this::transform${field.to}); |
| return newVal != oldVal ? (builder != null ? builder : creator.get()).${field.name}(newVal) : builder; |
| #elseif ( $field.type == "DOM" ) |
| XmlNode oldVal = target.get${capField}(); |
| XmlNode newVal = transform(oldVal); |
| return newVal != oldVal ? (builder != null ? builder : creator.get()).${field.name}(newVal) : builder; |
| #elseif ( $field.type == "boolean" || $field.type == "int" || $field.type == "java.nio.file.Path" ) |
| // nothing to do, the transformer only handles strings |
| return builder; |
| #else |
| // TODO: type=${field.type} to=${field.to} multiplicity=${field.multiplicity} |
| #end |
| } |
| #end |
| |
| #end |
| #end |
| protected <T> List<T> transform(List<T> list, UnaryOperator<T> transformer) { |
| List<T> newList = list; |
| for (int i = 0; i < list.size(); i++) { |
| T oldVal = list.get(i); |
| T newVal = transformer.apply(oldVal); |
| if (newVal != oldVal) { |
| if (newList == list) { |
| newList = new ArrayList<>(list); |
| } |
| newList.set(i, newVal); |
| } |
| } |
| return newList; |
| } |
| |
| protected <T> Map<String, T> transform(Map<String, T> map, UnaryOperator<T> transformer) { |
| Map<String, T> newMap = map; |
| for (String key : map.keySet()) { |
| T oldVal = map.get(key); |
| T newVal = transformer.apply(oldVal); |
| if (newVal != oldVal) { |
| if (newMap == map) { |
| newMap = new HashMap<>(map); |
| } |
| newMap.put(key, newVal); |
| } |
| } |
| return newMap; |
| } |
| |
| protected XmlNode transform(XmlNode node) { |
| if (node != null) { |
| String oldValue = node.value(); |
| String newValue = transform(oldValue); |
| Map<String, String> oldAttrs = node.attributes(); |
| Map<String, String> newAttrs = transform(oldAttrs, this::transform); |
| List<XmlNode> oldChildren = node.children(); |
| List<XmlNode> newChildren = transform(oldChildren, this::transform); |
| if (oldValue != newValue || oldAttrs != newAttrs || oldChildren != newChildren) { |
| return XmlNode.newBuilder() |
| .name(node.name()) |
| .prefix(node.prefix()) |
| .namespaceUri(node.namespaceUri()) |
| .value(newValue) |
| .attributes(newAttrs) |
| .children(newChildren) |
| .inputLocation(node.inputLocation()) |
| .build(); |
| } |
| } |
| return node; |
| } |
| } |