<commit_before>/*
 * Orika - simpler, better and faster Java bean mapping
 *
 * Copyright (C) 2011-2013 Orika authors
 *
 * 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 ma.glasnost.orika.impl.generator;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import ma.glasnost.orika.MapEntry;
import ma.glasnost.orika.impl.util.StringUtil;
import ma.glasnost.orika.metadata.FieldMap;
import ma.glasnost.orika.metadata.Property;
import ma.glasnost.orika.metadata.Type;
import ma.glasnost.orika.metadata.TypeFactory;

public class Node {
    
    public Property property;
    public MultiOccurrenceVariableRef multiOccurrenceVar;
    public MultiOccurrenceVariableRef newDestination;
    public VariableRef elementRef;
    public VariableRef nullCheckFlag;
    public VariableRef shouldAddToCollectorFlag;
    public FieldMap value;
    public NodeList children;
    public Node parent;
    public Set<Node> mapped = new HashSet<Node>();
    public boolean addedToCollector;
    private boolean isSource;
    
    private Node(Property property, FieldMap fieldMap, Node parent, NodeList nodes, boolean isSource, int uniqueIndex) {
        
        this.isSource = isSource;
        String name = (isSource ? "source" : "destination"); 
        String propertySuffix = StringUtil.capitalize(property.getName());
        this.value = fieldMap;
        this.parent = parent;
        this.property = property;
        
        
        if (property.isMultiOccurrence()) {

            /*
             * Use a List for storing elements intended for an Array; this allows flexibility in case we
             * can't (or it's too difficult to) determine the total size up front.
             *
             * Also, use a List (of Map.Entry) for elements intended for a Map; since we need to add the
             * Entry as soon as it's created (while it has null key and value), we can't put() it into
             * it's destination map until the other properties have been given values.
             */
            Type<?> elementType = buildElementType(property, isSource);
            Type<?> destinationType = buildDestinationType(property, elementType);
            
            this.newDestination = new MultiOccurrenceVariableRef(destinationType, "new_" + name + propertySuffix + uniqueIndex);  
            String multiOccurrenceName;
            if (parent != null) {
                multiOccurrenceName = name(parent.elementRef.name(),name + propertySuffix);
            } else {
                multiOccurrenceName = name;
            } 
            this.multiOccurrenceVar = new MultiOccurrenceVariableRef(property, multiOccurrenceName);
            this.elementRef = new VariableRef(elementType, property.getName() + "_" + name + uniqueIndex + "Element");
            if (elementType != null && elementType.isPrimitive()) {
                this.nullCheckFlag = new VariableRef(TypeFactory.valueOf(Boolean.TYPE), property.getName() + "_" + name+ uniqueIndex + "ElementIsNull");
            }
            this.shouldAddToCollectorFlag = new VariableRef(TypeFactory.valueOf(Boolean.TYPE), 
                    property.getName() + "_" + name+ uniqueIndex + "ElementShouldBeAddedToCollector");
        } 
        
        if (nodes != null) {
            nodes.add(this);
            this.children = new NodeList(nodes);
        } else if (parent != null) {
            parent.children.add(this);
            this.children = new NodeList(parent.children);
        } else {
            this.children = new NodeList();
        }
    }

    private Type<?> primitiveSafeListType(Type<?> type) {
        if (type.isPrimitive()) {
            return type.getWrapperType();
        } else {
            return type;
        }
    }

    private Node(Property property, Node parent, boolean isSource, int uniqueIndex) {
        this(property, null, parent, null, isSource, uniqueIndex);
    }

    private Node(Property property, FieldMap fieldMap, Node parent, boolean isSource, int uniqueIndex) {
        this(property, fieldMap, parent, null, isSource, uniqueIndex);
    }

    private Node(Property property, FieldMap fieldMap, NodeList nodes, boolean isSource, int uniqueIndex) {
        this(property, fieldMap, null, nodes, isSource, uniqueIndex);
    }

    private String name(String value1, String defaultValue) {
        if (value1 != null && !"".equals(value1)) {
            return value1;
        } else {
            return defaultValue;
        }
    }

    /**
     * @return true if this Node has no children
     */
    public boolean isLeaf() {
        return children.isEmpty();
    }

    /**
     * @return true if this Node has no parent
     */
    public boolean isRoot() {
        return parent == null;
    }

    /**
     * @param type
     * @param isSource
     * @return
     */
    public FieldMap getMap() {
        TreeMap<Integer, FieldMap> nodes = new TreeMap<Integer, FieldMap>();

        for (Node child: children) {
            if (child.value != null) {

                int depth = 0;
                FieldMap value = child.value;
                Property prop = isSource ? value.getSource() : value.getDestination();
                while (prop.getContainer() != null) {
                    ++depth;
                    prop = prop.getContainer();
                }

                if (!nodes.containsKey(Integer.valueOf(depth))) {
                    nodes.put(Integer.valueOf(depth), value);
                }
            }
        }
        if (!nodes.isEmpty()) {
            return nodes.get(nodes.firstKey());
        } else {
            return null;
        }
    }

    public void mapped(Node node) {
        mapped.add(node);
    }

    public String toString() {<commit_msg>Remove unused field<commit_after>/*
 * Orika - simpler, better and faster Java bean mapping
 *
 * Copyright (C) 2011-2013 Orika authors
 *
 * 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 ma.glasnost.orika.impl.generator;

import ma.glasnost.orika.MapEntry;
import ma.glasnost.orika.impl.util.StringUtil;
import ma.glasnost.orika.metadata.FieldMap;
import ma.glasnost.orika.metadata.Property;
import ma.glasnost.orika.metadata.Type;
import ma.glasnost.orika.metadata.TypeFactory;

import java.util.*;

public class Node {

    public final Node parent;
    private final boolean isSource;
    public final Property property;
    public final FieldMap value;
    public final NodeList children;

    public MultiOccurrenceVariableRef multiOccurrenceVar;
    public MultiOccurrenceVariableRef newDestination;
    public VariableRef elementRef;
    public VariableRef nullCheckFlag;
    public VariableRef shouldAddToCollectorFlag;
    public boolean addedToCollector;

    private Node(Property property, FieldMap fieldMap, Node parent, NodeList nodes, boolean isSource, int uniqueIndex) {
        
        this.isSource = isSource;
        String name = (isSource ? "source" : "destination"); 
        String propertySuffix = StringUtil.capitalize(property.getName());
        this.value = fieldMap;
        this.parent = parent;
        this.property = property;
        
        
        if (property.isMultiOccurrence()) {

            /*
             * Use a List for storing elements intended for an Array; this allows flexibility in case we
             * can't (or it's too difficult to) determine the total size up front.
             *
             * Also, use a List (of Map.Entry) for elements intended for a Map; since we need to add the
             * Entry as soon as it's created (while it has null key and value), we can't put() it into
             * it's destination map until the other properties have been given values.
             */
            Type<?> elementType = buildElementType(property, isSource);
            Type<?> destinationType = buildDestinationType(property, elementType);
            
            this.newDestination = new MultiOccurrenceVariableRef(destinationType, "new_" + name + propertySuffix + uniqueIndex);  
            String multiOccurrenceName;
            if (parent != null) {
                multiOccurrenceName = name(parent.elementRef.name(),name + propertySuffix);
            } else {
                multiOccurrenceName = name;
            } 
            this.multiOccurrenceVar = new MultiOccurrenceVariableRef(property, multiOccurrenceName);
            this.elementRef = new VariableRef(elementType, property.getName() + "_" + name + uniqueIndex + "Element");
            if (elementType != null && elementType.isPrimitive()) {
                this.nullCheckFlag = new VariableRef(TypeFactory.valueOf(Boolean.TYPE), property.getName() + "_" + name+ uniqueIndex + "ElementIsNull");
            }
            this.shouldAddToCollectorFlag = new VariableRef(TypeFactory.valueOf(Boolean.TYPE), 
                    property.getName() + "_" + name+ uniqueIndex + "ElementShouldBeAddedToCollector");
        } 
        
        if (nodes != null) {
            nodes.add(this);
            this.children = new NodeList(nodes);
        } else if (parent != null) {
            parent.children.add(this);
            this.children = new NodeList(parent.children);
        } else {
            this.children = new NodeList();
        }
    }

    private Type<?> primitiveSafeListType(Type<?> type) {
        if (type.isPrimitive()) {
            return type.getWrapperType();
        } else {
            return type;
        }
    }

    private Node(Property property, Node parent, boolean isSource, int uniqueIndex) {
        this(property, null, parent, null, isSource, uniqueIndex);
    }

    private Node(Property property, FieldMap fieldMap, Node parent, boolean isSource, int uniqueIndex) {
        this(property, fieldMap, parent, null, isSource, uniqueIndex);
    }

    private Node(Property property, FieldMap fieldMap, NodeList nodes, boolean isSource, int uniqueIndex) {
        this(property, fieldMap, null, nodes, isSource, uniqueIndex);
    }

    private String name(String value1, String defaultValue) {
        if (value1 != null && !"".equals(value1)) {
            return value1;
        } else {
            return defaultValue;
        }
    }

    /**
     * @return true if this Node has no children
     */
    public boolean isLeaf() {
        return children.isEmpty();
    }

    /**
     * @return true if this Node has no parent
     */
    public boolean isRoot() {
        return parent == null;
    }

    public FieldMap getMap() {
        TreeMap<Integer, FieldMap> nodes = new TreeMap<Integer, FieldMap>();

        for (Node child: children) {
            if (child.value != null) {

                int depth = 0;
                FieldMap value = child.value;
                Property prop = isSource ? value.getSource() : value.getDestination();
                while (prop.getContainer() != null) {
                    ++depth;
                    prop = prop.getContainer();
                }

                if (!nodes.containsKey(Integer.valueOf(depth))) {
                    nodes.put(Integer.valueOf(depth), value);
                }
            }
        }
        if (!nodes.isEmpty()) {
            return nodes.get(nodes.firstKey());
        } else {
            return null;
        }
    }

    public String toString() {
{'fraction_non_alphanumeric': 0.09397434863273373, 'fraction_numerical': 0.0027425990158909414, 'mean_word_length': 2.290339702760085, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6959361', 'n_tokens_mistral': 3247, 'n_tokens_neox': 3171, 'n_words': 978}