#* 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.Function; 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 import org.apache.maven.internal.xml.XmlNodeImpl; @Generated public class ${className} { private final Function transformer; public ${className}(Function 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 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 oldVal = target.get${capField}(); List 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 props = target.get${capField}(); Map newProps = null; for (Map.Entry 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 List transform(List list, Function transformer) { List 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 Map transform(Map map, Function transformer) { Map 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.getValue(); String newValue = transform(oldValue); Map oldAttrs = node.getAttributes(); Map newAttrs = transform(oldAttrs, this::transform); List oldChildren = node.getChildren(); List newChildren = transform(oldChildren, this::transform); if (oldValue != newValue || oldAttrs != newAttrs || oldChildren != newChildren) { return new XmlNodeImpl(node.getPrefix(), node.getNamespaceUri(), node.getName(), newValue, newAttrs, newChildren, node.getInputLocation()); } } return node; } }