001/* 002 * Copyright 2020 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.core.util.dom; 017 018import java.util.ArrayList; 019import java.util.HashSet; 020import java.util.List; 021import java.util.Set; 022 023import org.apache.commons.lang3.StringUtils; 024import org.w3c.dom.Element; 025import org.w3c.dom.Node; 026import org.w3c.dom.NodeList; 027 028/** 029 * Some useful utility methods for {@link Element} use 030 */ 031public final class DOMUtils 032{ 033 private DOMUtils() 034 { 035 // Empty constructor 036 } 037 038 /** 039 * Retrieves all child elements of the given DOM element. 040 * @param element The DOM element to analyze 041 * @return a {@link List} of child elements instances 042 */ 043 public static List<Element> getChildElements(Element element) 044 { 045 if (element == null) 046 { 047 throw new IllegalArgumentException("The element must not be null"); 048 } 049 050 List<Element> elements = new ArrayList<>(); 051 052 NodeList nodes = element.getChildNodes(); 053 for (int i = 0; i < nodes.getLength(); i++) 054 { 055 Node node = nodes.item(i); 056 if (node.getNodeType() == Node.ELEMENT_NODE) 057 { 058 elements.add((Element) node); 059 } 060 } 061 062 return elements; 063 } 064 065 /** 066 * Get the first child element of the given DOM element. 067 * @param element The DOM element to analyze 068 * @return the first child element or null if there is no child element 069 */ 070 public static Element getFirstChildElement(Element element) 071 { 072 if (element == null) 073 { 074 throw new IllegalArgumentException("The element must not be null"); 075 } 076 077 NodeList nodes = element.getChildNodes(); 078 for (int i = 0; i < nodes.getLength(); i++) 079 { 080 Node node = nodes.item(i); 081 if (node.getNodeType() == Node.ELEMENT_NODE) 082 { 083 return (Element) node; 084 } 085 } 086 087 return null; 088 } 089 090 /** 091 * Retrieves some child elements of the given DOM element 092 * If some elements have the same tag name, only the first of these elements is retrieved 093 * @param element the DOM element to analyze 094 * @return a {@link List} of child elements instances 095 */ 096 public static List<Element> getUniqueChildElements(Element element) 097 { 098 if (element == null) 099 { 100 throw new IllegalArgumentException("The element must not be null"); 101 } 102 103 List<Element> elements = new ArrayList<>(); 104 Set<String> tagNames = new HashSet<>(); 105 106 NodeList nodes = element.getChildNodes(); 107 for (int i = 0; i < nodes.getLength(); i++) 108 { 109 Node node = nodes.item(i); 110 String dataName = node.getNodeName(); 111 if (!tagNames.contains(dataName) && node.getNodeType() == Node.ELEMENT_NODE) 112 { 113 elements.add((Element) node); 114 tagNames.add(dataName); 115 } 116 } 117 118 return elements; 119 } 120 121 /** 122 * Retrieves all child elements of the given DOM element that match the given element name. 123 * Only look at the direct child level of the given element. 124 * Do not go into further depth (in contrast to the DOM API's getElementsByTagName method). 125 * @param element The DOM element to analyze 126 * @param name The child element name to look for 127 * @return a {@link List} of child elements instances 128 */ 129 public static List<Element> getChildElementsByTagName(Element element, String name) 130 { 131 if (element == null) 132 { 133 throw new IllegalArgumentException("The element must not be null"); 134 } 135 136 if (StringUtils.isEmpty(name)) 137 { 138 throw new IllegalArgumentException("The name must not be empty"); 139 } 140 141 List<Element> elements = new ArrayList<>(); 142 143 NodeList nodes = element.getChildNodes(); 144 for (int i = 0; i < nodes.getLength(); i++) 145 { 146 Node node = nodes.item(i); 147 if (node.getNodeType() == Node.ELEMENT_NODE && name.equals(node.getNodeName())) 148 { 149 elements.add((Element) node); 150 } 151 } 152 153 return elements; 154 } 155 156 /** 157 * Retrieves the first child element of the given DOM element that matches the given element name. 158 * Only look at the direct child level of the given element. Do not go into further depth. 159 * @param element The DOM element to analyze 160 * @param name The child element name to look for 161 * @return the first child element instance 162 */ 163 public static Element getChildElementByTagName(Element element, String name) 164 { 165 if (element == null) 166 { 167 throw new IllegalArgumentException("The element must not be null"); 168 } 169 170 if (StringUtils.isEmpty(name)) 171 { 172 throw new IllegalArgumentException("The name must not be empty"); 173 } 174 175 NodeList nodes = element.getChildNodes(); 176 for (int i = 0; i < nodes.getLength(); i++) 177 { 178 Node node = nodes.item(i); 179 if (node.getNodeType() == Node.ELEMENT_NODE && name.equals(node.getNodeName())) 180 { 181 return (Element) node; 182 } 183 } 184 185 return null; 186 } 187 188 /** 189 * Checks if the given DOM element has a child element that matches the given element name. 190 * @param element The DOM element to analyze 191 * @param name The child element name to look for 192 * @return <code>true</code> if the given DOM element has a child element that matches the given element name, <code>false</code> otherwise 193 */ 194 public static boolean hasChildElement(Element element, String name) 195 { 196 return getChildElementByTagName(element, name) != null; 197 } 198}