<commit_before>package org.verapdf.features.pb.objects;

import org.apache.pdfbox.pdmodel.graphics.color.PDColor;
import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDDocumentOutline;
import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDOutlineItem;
import org.verapdf.exceptions.featurereport.FeaturesTreeNodeException;
import org.verapdf.features.FeaturesObjectTypesEnum;
import org.verapdf.features.IFeaturesObject;
import org.verapdf.features.pb.tools.PBCreateNodeHelper;
import org.verapdf.features.tools.ErrorsHelper;
import org.verapdf.features.tools.FeatureTreeNode;
import org.verapdf.features.tools.FeaturesCollection;

/**
 * Feature object for outlines
 *
 * @author <NAME>
 */
public class PBOutlinesFeaturesObject implements IFeaturesObject {

    private static final int RGB_COLORS_NUMBER = 3;
    private static final int RGB_RED_COLOR_NUMBER = 0;
    private static final int RGB_GREEN_COLOR_NUMBER = 1;
    private static final int RGB_BLUE_COLOR_NUMBER = 2;

    private PDDocumentOutline outline;

    /**
     * Constructs new OutputIntent Feature Object
     *
     * @param outline
     *            pdfbox class represents outlines object
     */
    public PBOutlinesFeaturesObject(PDDocumentOutline outline) {
        this.outline = outline;
    }

    /**
     * @return OUTLINES instance of the FeaturesObjectTypesEnum enumeration
     */
    @Override
    public FeaturesObjectTypesEnum getType() {
        return FeaturesObjectTypesEnum.OUTLINES;
    }

    /**
     * Reports featurereport into collection
     *
     * @param collection
     *            collection for feature report
     * @return FeatureTreeNode class which represents a root node of the
     *         constructed collection tree
     * @throws FeaturesTreeNodeException
     *             occurs when wrong features tree node constructs
     */
    @Override
    public FeatureTreeNode reportFeatures(FeaturesCollection collection)
            throws FeaturesTreeNodeException {
        if (outline != null) {
            FeatureTreeNode root = FeatureTreeNode.newRootInstance("outlines");

            if (outline.children() != null) {
                for (PDOutlineItem item : outline.children()) {
                    createItem(item, root, collection);
                }
            }

            collection
                    .addNewFeatureTree(FeaturesObjectTypesEnum.OUTLINES, root);
            return root;
        }
        return null;
    }

    private static void createItem(PDOutlineItem item, FeatureTreeNode root,
            FeaturesCollection collection) throws FeaturesTreeNodeException {
        if (item != null) {
            FeatureTreeNode itemNode = FeatureTreeNode.newChildInstance(
                    "outline", root);

            PBCreateNodeHelper.addNotEmptyNode("title", item.getTitle(),
                    itemNode);

            if (item.getTextColor() != null) {
                FeatureTreeNode color = FeatureTreeNode.newChildInstance(
                        "color", itemNode);

                PDColor clr = item.getTextColor();
                float[] rgb = clr.getComponents();
                if (rgb.length == RGB_COLORS_NUMBER) {
                    FeatureTreeNode.newChildInstanceWithValue("red",
                            String.valueOf(rgb[RGB_RED_COLOR_NUMBER]), color);
                    FeatureTreeNode.newChildInstanceWithValue("green",
                            String.valueOf(rgb[RGB_GREEN_COLOR_NUMBER]), color);
                    FeatureTreeNode.newChildInstanceWithValue("blue",
                            String.valueOf(rgb[RGB_BLUE_COLOR_NUMBER]), color);
                } else {
                    color.addAttribute(ErrorsHelper.ERRORID,
                            ErrorsHelper.OUTLINESCOLOR_ID);
                    ErrorsHelper.addErrorIntoCollection(collection,
                            ErrorsHelper.OUTLINESCOLOR_ID,
                            ErrorsHelper.OUTLINESCOLOR_MESSAGE);
                }
            }

            FeatureTreeNode.newChildInstanceWithValue("italic",
                    String.valueOf(item.isItalic()), itemNode);
            FeatureTreeNode.newChildInstanceWithValue("bold",
                    String.valueOf(item.isBold()), itemNode);

            for (PDOutlineItem child : item.children()) {
                createItem(child, itemNode, collection);
            }
        }
    }
}<commit_msg>Outlines features object fix.<commit_after>package org.verapdf.features.pb.objects;

import org.apache.pdfbox.pdmodel.graphics.color.PDColor;
import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDDocumentOutline;
import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDOutlineItem;
import org.verapdf.exceptions.featurereport.FeaturesTreeNodeException;
import org.verapdf.features.FeaturesObjectTypesEnum;
import org.verapdf.features.IFeaturesObject;
import org.verapdf.features.pb.tools.PBCreateNodeHelper;
import org.verapdf.features.tools.ErrorsHelper;
import org.verapdf.features.tools.FeatureTreeNode;
import org.verapdf.features.tools.FeaturesCollection;

import java.util.HashSet;
import java.util.Set;

/**
 * Feature object for outlines
 *
 * @author <NAME>
 */
public class PBOutlinesFeaturesObject implements IFeaturesObject {

    private static final int RGB_COLORS_NUMBER = 3;
    private static final int RGB_RED_COLOR_NUMBER = 0;
    private static final int RGB_GREEN_COLOR_NUMBER = 1;
    private static final int RGB_BLUE_COLOR_NUMBER = 2;

    private PDDocumentOutline outline;

    /**
     * Constructs new OutputIntent Feature Object
     *
     * @param outline
     *            pdfbox class represents outlines object
     */
    public PBOutlinesFeaturesObject(PDDocumentOutline outline) {
        this.outline = outline;
    }

    /**
     * @return OUTLINES instance of the FeaturesObjectTypesEnum enumeration
     */
    @Override
    public FeaturesObjectTypesEnum getType() {
        return FeaturesObjectTypesEnum.OUTLINES;
    }

    /**
     * Reports featurereport into collection
     *
     * @param collection
     *            collection for feature report
     * @return FeatureTreeNode class which represents a root node of the
     *         constructed collection tree
     * @throws FeaturesTreeNodeException
     *             occurs when wrong features tree node constructs
     */
    @Override
    public FeatureTreeNode reportFeatures(FeaturesCollection collection)
            throws FeaturesTreeNodeException {
        if (outline != null) {
            FeatureTreeNode root = FeatureTreeNode.newRootInstance("outlines");

            if (outline.children() != null) {
                Set<PDOutlineItem> items = new HashSet<>();
                for (PDOutlineItem item : outline.children()) {
                    if (!items.contains(item)) {
                        createItem(item, root, collection, items);
                    }
                }
            }

            collection
                    .addNewFeatureTree(FeaturesObjectTypesEnum.OUTLINES, root);
            return root;
        }
        return null;
    }

    private static void createItem(PDOutlineItem item, FeatureTreeNode root,
                                   FeaturesCollection collection, Set<PDOutlineItem> items) throws FeaturesTreeNodeException {
        if (item != null) {
            items.add(item);
            FeatureTreeNode itemNode = FeatureTreeNode.newChildInstance(
                    "outline", root);

            PBCreateNodeHelper.addNotEmptyNode("title", item.getTitle(),
                    itemNode);

            if (item.getTextColor() != null) {
                FeatureTreeNode color = FeatureTreeNode.newChildInstance(
                        "color", itemNode);

                PDColor clr = item.getTextColor();
                float[] rgb = clr.getComponents();
                if (rgb.length == RGB_COLORS_NUMBER) {
                    FeatureTreeNode.newChildInstanceWithValue("red",
                            String.valueOf(rgb[RGB_RED_COLOR_NUMBER]), color);
                    FeatureTreeNode.newChildInstanceWithValue("green",
                            String.valueOf(rgb[RGB_GREEN_COLOR_NUMBER]), color);
                    FeatureTreeNode.newChildInstanceWithValue("blue",
                            String.valueOf(rgb[RGB_BLUE_COLOR_NUMBER]), color);
                } else {
                    color.addAttribute(ErrorsHelper.ERRORID,
                            ErrorsHelper.OUTLINESCOLOR_ID);
                    ErrorsHelper.addErrorIntoCollection(collection,
                            ErrorsHelper.OUTLINESCOLOR_ID,
                            ErrorsHelper.OUTLINESCOLOR_MESSAGE);
                }
            }

            FeatureTreeNode.newChildInstanceWithValue("italic",
                    String.valueOf(item.isItalic()), itemNode);
            FeatureTreeNode.newChildInstanceWithValue("bold",
                    String.valueOf(item.isBold()), itemNode);

            for (PDOutlineItem child : item.children()) {
                if (!items.contains(item)) {
                    createItem(child, itemNode, collection, items);
                }
            }
        }
    }
}
{'fraction_non_alphanumeric': 0.07892183288409703, 'fraction_numerical': 0.0008625336927223719, 'mean_word_length': 2.1637107776261937, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 8, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3233160', 'n_tokens_mistral': 2368, 'n_tokens_neox': 2248, 'n_words': 458}