All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.mustangproject.util.NodeMap Maven / Gradle / Ivy

Go to download

FOSS Java library to read, write and validate european electronic invoices and orders in the UN/CEFACT Cross Industry Invoice based formats Factur-X/ZUGFeRD, XRechnung and Order-X in your invoice PDFs.

The newest version!
/**
 * *********************************************************************
 * 

* Copyright (c) 2024 Jan N. Klug *

* Use is subject to license terms. *

* 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 org.mustangproject.util; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; /** * The {@link NodeMap} contains a {@link Map} representation of DOM object * It can be constructed either from the children of a single {@link Node} or a {@link NodeList}. */ public class NodeMap { private final Map> map = new HashMap<>(); /** * Create a new {@link NodeMap} * The {@link Node} that is passed to the constructor must not be null. * The {@link NodeMap} will be empty when no child nodes are present. * * @param node the node that shall be represented by this {@link NodeMap} * @throws IllegalArgumentException when argument is null */ public NodeMap(Node node) { if (node == null) { throw new IllegalArgumentException("node cannot be null"); } if (node.hasChildNodes()) { mapNodeList(node.getChildNodes()); } } public NodeMap(NodeList nodeList) { if (nodeList == null) { throw new IllegalArgumentException("nodeList cannot be null"); } mapNodeList(nodeList); } /** * Get matching node by {@code LocalName} * In case more than one node matches, it is not guaranteed that the first match is selected * * @param localNames one or more {@code LocalName}s * @return the matching node */ public Optional getNode(String... localNames) { return getAllNodes(localNames).findAny(); } /** * Get a {@link NodeMap} of the child of a matching node by {@code LocalName} * In case more than one node matches, it is not guaranteed that the first match is selected * * @param localNames one or more {@code LocalName}s * @return the {@link NodeMap} representation of the matching node */ public Optional getAsNodeMap(String... localNames) { return getNode(localNames).filter(Node::hasChildNodes).map(NodeMap::new); } /** * Get the text content of a matching node * In case more than one node matches, it is not guaranteed that the first match is selected * * @param localNames one or more {@code LocalName}s * @return the text content of the matching node */ public Optional getAsString(String... localNames) { return getNode(localNames).map(Node::getTextContent); } /** * Get the text content of a matching node * In case more than one node matches, it is not guaranteed that the first match is selected * * @param localNames one or more {@code LocalName}s * @return the text content of the matching node, converted to BigDecimal */ public Optional getAsBigDecimal(String... localNames) { return getNode(localNames).map(Node::getTextContent).map(s->{ try { return new BigDecimal(s.trim()); } catch (NumberFormatException e) { return null; } }); } /** * Get the text content of a matching node * In case more than one node matches, it is not guaranteed that the first match is selected * * @param localNames one or more {@code LocalName}s * @return the text content of the matching node or {@code null} when no matching node could be found */ public String getAsStringOrNull(String... localNames) { return getAsString(localNames).orElse(null); } /** * Get all matching nodes * * @param localNames one or more {@code LocalName}s * @return a {@code Stream} that contains all matching nodes (can be empty if nothing matches) */ public Stream getAllNodes(String... localNames) { List localNamesList = Arrays.asList(localNames); return map.entrySet().stream().filter(e -> localNamesList.contains(e.getKey())).flatMap(e -> e.getValue().stream()); } private void mapNodeList(NodeList nodeList) { IntStream.range(0, nodeList.getLength()).mapToObj(nodeList::item) .filter(node -> node != null && node.getLocalName() != null) .forEach(node -> map.computeIfAbsent(node.getLocalName(), k -> new ArrayList<>()).add(node)); } @Override public String toString() { return map.toString(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy