blob: 8eaac496fbc6c63b626c02d03388cd19908ac1e5 [file] [log] [blame]
#*
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.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.codehaus.plexus.util.xml.Xpp3Dom;
@Generated
public class ${className} {
private final Function<String, String> transformer;
public ${className}(Function<String, 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;
}
${class.name}.Builder builder = ${class.name}.newBuilder(target);
#foreach ( $field in $allFields )
transform${field.modelClass.name}_${Helper.capitalise($field.name)}(builder, target);
#end
return builder.build();
}
#foreach ( $field in $allFields )
#set ( $capField = ${Helper.capitalise($field.name)} )
protected void transform${class.name}_${capField}(${class.name}.Builder builder, ${class.name} target) {
#if ( $field.type == "String" )
String newVal = transform(target.get${capField}());
builder.${field.name}(newVal != target.get${capField}() ? newVal : null);
#elseif ( $field.type == "java.util.List" && $field.to == "String" && $field.multiplicity == "*" )
builder.${field.name}(transform(target.get${capField}(), this::transform));
#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.${field.name}(newProps);
}
newProps.put(entry.getKey(), newVal);
}
}
#elseif ( $field.to && $field.multiplicity == "1" )
${field.to} newVal = transform${field.to}(target.get${capField}());
builder.${field.name}(newVal != target.get${capField}() ? newVal : null);
#elseif ( $field.to && $field.multiplicity == "*" )
builder.${field.name}(transform(target.get${capField}(), this::transform${field.to}));
#elseif ( $field.type == "DOM" )
XmlNode newVal = transform(target.get${capField}());
builder.${field.name}(newVal != target.get${capField}() ? newVal : null);
#elseif ( $field.type == "boolean" || $field.type == "int" || $field.type == "java.nio.file.Path" )
// nothing to do, the transformer only handles strings
#else
// TODO: type=${field.type} to=${field.to} multiplicity=${field.multiplicity}
#end
}
#end
#end
#end
protected <T> List<T> transform(List<T> list, Function<T, T> transformer) {
List<T> newList = null;
for (int i = 0; i < list.size(); i++) {
T newVal = transformer.apply(list.get(i));
if (newVal != list.get(i)) {
if (newList == null) {
newList = new ArrayList<>(list);
}
newList.set(i, newVal);
}
}
return newList;
}
protected XmlNode transform(XmlNode node) {
if (node != null) {
Xpp3Dom xpp = new Xpp3Dom(node);
transform(xpp);
return xpp.getDom();
}
return node;
}
protected void transform(Xpp3Dom dom) {
if (dom != null) {
String org, val;
// Content
org = dom.getValue();
val = transform(org);
if (org != val) {
dom.setValue(val);
}
// Attributes
for (String attr : dom.getAttributeNames()) {
org = dom.getAttribute(attr);
val = transform(org);
if (org != val) {
dom.setAttribute(attr, val);
}
}
// Children
for (int i = 0, l = dom.getChildCount(); i < l; i++) {
transform(dom.getChild(i));
}
}
}
}