/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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.apache.cxf.tools.util; import java.io.BufferedInputStream; import java.io.File; import java.io.InputStream; import java.nio.file.Files; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Stack; import javax.xml.namespace.QName; import javax.xml.stream.XMLStreamReader; import org.apache.cxf.staxutils.StaxUtils; import org.apache.cxf.tools.common.Tag; public final class ToolsStaxUtils { private ToolsStaxUtils() { } public static List<Tag> getTags(final File source) throws Exception { List<Tag> tags = new ArrayList<>(); List<String> ignoreEmptyTags = Arrays.asList(new String[]{"sequence"}); try (InputStream is = new BufferedInputStream(Files.newInputStream(source.toPath()))) { XMLStreamReader reader = StaxUtils.createXMLStreamReader(is); Tag newTag = null; int count = 0; QName checkingPoint = null; Stack<Tag> stack = new Stack<Tag>(); while (reader.hasNext()) { int event = reader.next(); if (checkingPoint != null) { count++; } if (event == XMLStreamReader.START_ELEMENT) { newTag = new Tag(); newTag.setName(reader.getName()); if (ignoreEmptyTags.contains(reader.getLocalName())) { checkingPoint = reader.getName(); } for (int i = 0; i < reader.getAttributeCount(); i++) { newTag.getAttributes().put(reader.getAttributeName(i), reader.getAttributeValue(i)); } stack.push(newTag); } if (event == XMLStreamReader.CHARACTERS) { newTag.setText(reader.getText()); } if (event == XMLStreamReader.END_ELEMENT) { Tag startTag = stack.pop(); if (checkingPoint != null && checkingPoint.equals(reader.getName())) { if (count == 1) { //Tag is empty, and it's in the ignore collection, so we just skip this tag } else { tags.add(startTag); } count = 0; checkingPoint = null; } else { tags.add(startTag); } } } reader.close(); } return tags; } public static Tag getTagTree(final File source) throws Exception { return getTagTree(source, new ArrayList<>()); } public static Tag getTagTree(final File source, final List<String> ignoreAttr) throws Exception { try (InputStream is = new BufferedInputStream(Files.newInputStream(source.toPath()))) { return getTagTree(is, ignoreAttr, null); } } public static Tag getTagTree(final File source, final List<String> ignoreAttr, Map<QName, Set<String>> types) throws Exception { try (InputStream is = new BufferedInputStream(Files.newInputStream(source.toPath()))) { return getTagTree(is, ignoreAttr, types); } } public static Tag getTagTree(final InputStream is, final List<String> ignoreAttr, Map<QName, Set<String>> types) throws Exception { Tag root = new Tag(); root.setName(new QName("root", "root")); XMLStreamReader reader = StaxUtils.createXMLStreamReader(is); Tag newTag = null; Tag currentTag = root; while (reader.hasNext()) { int event = reader.next(); if (event == XMLStreamReader.START_ELEMENT) { newTag = new Tag(); newTag.setName(reader.getName()); if (!ignoreAttr.isEmpty()) { newTag.getIgnoreAttr().addAll(ignoreAttr); } for (int i = 0; i < reader.getAttributeCount(); i++) { //probably a qname to a type, pull namespace in differently String tp = reader.getAttributeValue(i); if (isType(types, reader.getName(), reader.getAttributeName(i))) { int idx = tp.indexOf(':'); if (idx > 0 && tp.length() > idx && tp.substring(idx + 1).indexOf(':') == -1) { String pfx = tp.substring(0, idx); String ns = reader.getNamespaceURI(pfx); if (ns != null) { tp = "{" + ns + "}" + tp.substring(idx + 1); } } else { String ns = reader.getNamespaceURI(""); if (ns != null) { tp = "{" + ns + "}" + tp.substring(idx + 1); } } } newTag.getAttributes().put(reader.getAttributeName(i), tp); } newTag.setParent(currentTag); currentTag.getTags().add(newTag); currentTag = newTag; } if (event == XMLStreamReader.CHARACTERS) { newTag.setText(reader.getText()); } if (event == XMLStreamReader.END_ELEMENT) { currentTag = currentTag.getParent(); } } reader.close(); return root; } private static boolean isType(Map<QName, Set<String>> types, QName name, QName attributeName) { if (types == null) { return false; } Set<String> a = types.get(name); return a != null && a.contains(attributeName.getLocalPart()); } }