/* * Copyright 2014 the original author or authors. * * 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.gradle.api.internal.artifacts.ivyservice.ivyresolve.parser; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import java.io.*; import java.util.LinkedList; import java.util.List; public final class PomDomParser { private PomDomParser() {} public static String getTextContent(Element element) { StringBuilder result = new StringBuilder(); NodeList childNodes = element.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { Node child = childNodes.item(i); switch (child.getNodeType()) { case Node.CDATA_SECTION_NODE: case Node.TEXT_NODE: result.append(child.getNodeValue()); break; default: break; } } return result.toString(); } public static String getFirstChildText(Element parentElem, String name) { Element node = getFirstChildElement(parentElem, name); if (node != null) { return getTextContent(node); } else { return null; } } public static Element getFirstChildElement(Element parentElem, String name) { if (parentElem == null) { return null; } NodeList childs = parentElem.getChildNodes(); for (int i = 0; i < childs.getLength(); i++) { Node node = childs.item(i); if (node instanceof Element && name.equals(node.getNodeName())) { return (Element) node; } } return null; } public static List<Element> getAllChilds(Element parent) { List<Element> r = new LinkedList<Element>(); if (parent != null) { NodeList childs = parent.getChildNodes(); for (int i = 0; i < childs.getLength(); i++) { Node node = childs.item(i); if (node instanceof Element) { r.add((Element) node); } } } return r; } public static final class AddDTDFilterInputStream extends FilterInputStream { private static final int MARK = 10000; private static final String DOCTYPE = "<!DOCTYPE project SYSTEM \"m2-entities.ent\">\n"; private int count; private byte[] prefix = DOCTYPE.getBytes(); public AddDTDFilterInputStream(InputStream in) throws IOException { super(new BufferedInputStream(in)); this.in.mark(MARK); // TODO: we should really find a better solution for this... // maybe we could use a FilterReader instead of a FilterInputStream? int byte1 = this.in.read(); int byte2 = this.in.read(); int byte3 = this.in.read(); if (byte1 == 239 && byte2 == 187 && byte3 == 191) { // skip the UTF-8 BOM this.in.mark(MARK); } else { this.in.reset(); } int bytesToSkip = 0; LineNumberReader reader = new LineNumberReader(new InputStreamReader(this.in, "UTF-8"), 100); String firstLine = reader.readLine(); if (firstLine != null) { String trimmed = firstLine.trim(); if (trimmed.startsWith("<?xml ")) { int endIndex = trimmed.indexOf("?>"); String xmlDecl = trimmed.substring(0, endIndex + 2); prefix = (xmlDecl + "\n" + DOCTYPE).getBytes(); bytesToSkip = xmlDecl.getBytes().length; } } this.in.reset(); for (int i = 0; i < bytesToSkip; i++) { this.in.read(); } } public int read() throws IOException { if (count < prefix.length) { return prefix[count++]; } return super.read(); } public int read(byte[] b, int off, int len) throws IOException { if (b == null) { throw new NullPointerException(); } else if ((off < 0) || (off > b.length) || (len < 0) || ((off + len) > b.length) || ((off + len) < 0)) { throw new IndexOutOfBoundsException(); } else if (len == 0) { return 0; } int nbrBytesCopied = 0; if (count < prefix.length) { int nbrBytesFromPrefix = Math.min(prefix.length - count, len); System.arraycopy(prefix, count, b, off, nbrBytesFromPrefix); nbrBytesCopied = nbrBytesFromPrefix; } if (nbrBytesCopied < len) { nbrBytesCopied += in.read(b, off + nbrBytesCopied, len - nbrBytesCopied); } count += nbrBytesCopied; return nbrBytesCopied; } } }