Java tutorial
/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * Copyright (c) 2001 - 2013 Object Refinery Ltd, Hitachi Vantara and Contributors.. All rights reserved. */ package org.pentaho.reporting.libraries.xmlns.parser; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.xml.sax.EntityResolver; import org.xml.sax.InputSource; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.HashMap; /** * Resolves the JFreeReport DTD specification and routes the parser to a local copy. * * @author Thomas Morgner */ public final class ParserEntityResolver implements EntityResolver { private static final Log logger = LogFactory.getLog(ParserEntityResolver.class); /** * The hashtable for the known entities (deprecated DTDs). */ private final HashMap deprecatedDTDs; /** * The hashtable for the known entities. */ private final HashMap dtds; /** * The singleton instance of this entity resolver. */ private static ParserEntityResolver singleton; /** * Creates a new, uninitialized ParserEntityResolver. */ private ParserEntityResolver() { dtds = new HashMap(); deprecatedDTDs = new HashMap(); } /** * Defines a DTD used to validate the report definition. Your XMLParser must be a validating parser for this feature * to work. * * @param publicID the public ID. * @param location the URL. * @return A boolean. */ public boolean setDTDLocation(final String publicID, final URL location) { if (isValid(location)) { this.dtds.put(publicID, location); return true; } else { logger.warn("Validate location failed for " + publicID + " location: " + location); return false; } } /** * Defines a DTD used to validate the report definition. Your XMLParser must be a validating parser for this feature * to work. * * @param systemId the system ID for the DTD. * @param publicID the public ID. * @param location the URL. * @return A boolean. */ public boolean setDTDLocation(final String publicID, final String systemId, final URL location) { if (isValid(location)) { this.dtds.put(publicID, location); this.dtds.put(systemId, location); return true; } else { logger.warn("Validate location failed for " + publicID + " location: " + location); return false; } } /** * Sets the location of the DTD. This is used for validating XML parsers to validate the structure of the report * definition. * * @param publicID the id. * @return the URL for the DTD. */ public URL getDTDLocation(final String publicID) { return (URL) dtds.get(publicID); } /** * Checks whether the speficied URL is readable. * * @param reportDtd the url pointing to the local DTD copy. * @return true, if the URL can be read, false otherwise. */ private boolean isValid(final URL reportDtd) { if (reportDtd == null) { return false; } try { final InputStream uc = reportDtd.openStream(); uc.close(); return true; } catch (IOException ioe) { return false; } } /** * Allow the application to resolve external entities. * <p/> * Resolves the DTD definition to point to a local copy, if the specified public ID is known to this resolver. * * @param publicId the public ID. * @param systemId the system ID. * @return The input source. */ public InputSource resolveEntity(final String publicId, final String systemId) { try { // cannot validate without public id ... if (publicId == null) { //Log.debug ("No PUBLIC ID, cannot continue"); if (systemId != null) { final URL location = getDTDLocation(systemId); if (location != null) { final InputSource inputSource = new InputSource(location.openStream()); inputSource.setSystemId(systemId); return inputSource; } } return null; } final URL location = getDTDLocation(publicId); if (location != null) { final InputSource inputSource = new InputSource(location.openStream()); inputSource.setSystemId(systemId); inputSource.setPublicId(publicId); return inputSource; } final String message = getDeprecatedDTDMessage(publicId); if (message != null) { logger.info(message); } else { logger.info("A public ID was given for the document, but it was unknown or invalid."); } return null; } catch (IOException ioe) { logger.warn("Unable to open specified DTD", ioe); } return null; } /** * Returns a default resolver, which is initialized to redirect the parser to a local copy of the JFreeReport DTDs. * * @return the default entity resolver. */ public static synchronized ParserEntityResolver getDefaultResolver() { if (singleton == null) { singleton = new ParserEntityResolver(); } return singleton; } /** * Defines that the given public ID should be deprecated and provides a log-message along with the deprecation. * * @param publicID the public id that should be considered deprecated. * @param message the message to present to the user to warn them about their use of deprecated DTDs. */ public void setDeprecatedDTDMessage(final String publicID, final String message) { deprecatedDTDs.put(publicID, message); } /** * Returns deprecation message for the given public ID. * * @param publicID the public id that should be considered deprecated. * @return the deprecation message or null if the ID is not considered deprecated. */ public String getDeprecatedDTDMessage(final String publicID) { return (String) deprecatedDTDs.get(publicID); } }