We updated to SonarQube 10.5 to finally get Java 21 support. Mostly works fine, but one file seems to make trouble for the SyntaxHighlighterVisitor.
The file in question is this:
/*****************************************************
* Copyright (c) Faktor Zehn GmbH - www.faktorzehn.de
*
* All Rights Reserved - Alle Rechte vorbehalten.
*****************************************************/
package org.faktorips.productdesigner.core.wrapper.structure;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.stream.Stream;
import org.faktorips.productdesigner.core.wrapper.ISearchable;
import org.faktorips.valueset.IntegerRange;
import org.linkki.util.Sequence;
import edu.umd.cs.findbugs.annotations.CheckForNull;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
/**
* Common interface for {@link ProductNode}, {@link AssociationNode} and {@link TableNode}.
*/
public sealed interface ProductStructureNode permits AssociationNode, TableAssociationNode, TableNode, ProductNode {
/** {@return the parent node} */
@CheckForNull
ProductStructureNode parent();
/** {@return the searchable product configuration element} */
ISearchable getSearchable();
Optional<String> getId();
/**
* Returns the children of the node to build the structure tree.
* <p>
* For a {@link ProductNode product node} the list of {@link AssociationNode association nodes}
* that are connected to the product is returned.
* <p>
* For a {@link AssociationNode association node} the list of {@link ProductNode product nodes}
* that wrap the targets of the association is returned.
*/
List<? extends ProductStructureNode> getChildren();
/** {@return the localized label for the given locale} */
String getLabel(Locale locale);
/** {@return the cardinality for this node} */
Optional<IntegerRange> getCardinality();
/** {@return the path from the root node to this node} */
Sequence<String> asPath();
/**
* Returns the children of the children of the node.
* <p>
* For a {@link ProductNode product node} the list of {@link ProductNode product nodes} that
* wrap the targets of the children {@link AssociationNode association nodes} is returned.
* <p>
* For a {@link AssociationNode association node} the list of {@link AssociationNode association
* nodes} that are connected to the children {@link ProductNode product nodes} is returned.
*/
default List<? extends ProductStructureNode> getChildrenOfChildren() {
List<? extends ProductStructureNode> children = getChildren();
return Stream.concat(
children.stream()
.map(ProductStructureNode::getChildren)
.flatMap(List::stream),
children.stream()
.filter(TableNode.class::isInstance))
.toList();
}
@SuppressFBWarnings(value = { "NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE",
"NP_NONNULL_RETURN_VIOLATION" }, justification = """
root is only set to non-null parents and can't change\
between the null check and the second call, as records are immutable.\
AssociationNodes always have a ProductNode parent.""")
default ProductStructureNode getRoot() {
ProductStructureNode root = this;
while (root != null && root.parent() != null) {
root = root.parent();
}
return root;
}
}