/** * Copyright (C) 2009-2015 Dell, Inc. * See annotations for authorship information * * ==================================================================== * 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.dasein.cloud.util; import org.w3c.dom.Document; import org.xml.sax.SAXException; import javax.annotation.Nonnull; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import java.io.IOException; import java.io.InputStream; import java.util.Stack; /** * A special class to minimize the issues associated with synchronization bugs in Xerces. It sucks that we have to do this, * but it has to be done. * <p>Created by George Reese: 2/21/13 10:16 AM</p> * @author George Reese * @version 2013.04 * @since 2013.04 */ public class XMLParser { static public class DBPair { public DocumentBuilderFactory factory; public DocumentBuilder builder; public void release() { builder.reset(); synchronized( xercesSucksWorkaround ) { xercesSucksWorkaround.push(this); } } } static private final Stack<DBPair> xercesSucksWorkaround = new Stack<DBPair>(); static public @Nonnull DBPair getCachedDocumentBuilder() throws ParserConfigurationException { synchronized( xercesSucksWorkaround ) { if( !xercesSucksWorkaround.isEmpty() ) { return xercesSucksWorkaround.pop(); } } DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = dbf.newDocumentBuilder(); DBPair pair = new DBPair(); pair.factory = dbf; pair.builder = builder; return pair; } static public Document parse(@Nonnull InputStream input) throws ParserConfigurationException, IOException, SAXException { DBPair pair = getCachedDocumentBuilder(); try { Document doc = pair.builder.parse(input); input.close(); return doc; } finally { pair.release(); } } }